簡體   English   中英

如何從多列中檢索“最后”非零值?

[英]How to retrieve “last” non-zero values from multiple columns?

考慮一個有11列的有序表:
timespan, val1, val2, val3, val4, val5, val6, val7, val8, val9 and val10

假設一組記錄如:

timespan     val1  val2  val3  val4  val5  val6  val7  val8  val9  val10
10/09/2011      0     0    60    80    40     0     0    40    80      0
10/10/2011      0    10    90    30    70    50    50    70    30     90
10/11/2011     10     0    20     0     0    60    60     0     0     20

我需要一個SQL查詢(對於SQL Server 2012),它返回所有列的最后(及時)非零值,val1,val2,...,即

val1  val2  val3  val4  val5  val6  val7  val8  val9  val10
  10    10    20    30    70    60    60    70    30     20

Subquery中可以找到類似的問題:如何從列中檢索最后一個非零值? 但它只適用於一列,並且包含更多列的泛化(如本例所示)似乎不實用。

你可以使用first_value()

select distinct first_value(val1) over (order by sign(val1) desc, timespan desc) as val1,
       first_value(val2) over (order by sign(val2) desc, timespan desc) as val2,
       . . .
from t;

通常,我反對使用select distinct作為聚合查詢的替代。 不幸的是,SQL Server支持first_value()作為窗口函數,但不提供聚合的等效項。

注意: sign()函數用於將零值放在最后。 如果你可以有負值,那么使用abs(sign())

另一種選擇是快速拆卸,然后是樞軸

Select *
 From  (
           Select top 1 with ties item,value
            From  YourTable
            UnPivot ( Value for Item in (val1,val2,val3,val4,val5,val6,val7,val8,val9,val10) ) u
            Where value<>0
            Order by Row_Number() over (Partition By item Order by timespan desc)
       ) src
 Pivot (max(value) For item in (val1,val2,val3,val4,val5,val6,val7,val8,val9,val10) ) p

返回

val1    val2    val3    val4    val5    val6    val7    val8    val9    val10
10      10      20      30      70      60      60      70      30      20

你可以使用下面的東西。 1.邏輯是首先取消值,然后刪除0個條目,然后計算最后的非零值為row_num = 1。

  1. 然后再次旋轉以獲得結果。

查詢如下

create table t
(timespan date,val1 int,val2 int,val3 int,val4 int,val5 int,val6 int,val7 int,val8 int,val9 int,val10 int);
insert into t values
('10/09/2011', 0, 0,60,80,40, 0, 0,40,80, 0)
,('10/10/2011', 0,10,90,30,70,50,50,70,30,90)
,('10/11/2011',10, 0,20, 0, 0,60,60, 0, 0,20);

select * 
    from
(
    select 
        value, Columns 
    from
    (
        select 
            timespan,
            value, 
            Columns, 
            row_number() over(partition by Columns order by timespan desc) r
        from
        (select * from t)s
        unpivot
        ( 
            value for Columns in 
                ([val1],[val2],[val3],[val4],[val5],[val6],[val7],[val8],[val9],[val10])
        )up
        where value<>0
    ) t 
    where r=1
 )s
pivot
(
    max(value) for Columns in 
        ([val1],[val2],[val3],[val4],[val5],[val6],[val7],[val8],[val9],[val10])
)p

看工作演示

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM