2017-10-11 59 views
5

考慮有序表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: how to retrieve the last non-zero value from a column?找到,但它只是作品對於一列以及包含更多列的泛化(在這種情況下)似乎不實際。

回答

1

您可以使用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())

1

另一種選擇是一個快速逆轉置,然後樞軸

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 
+0

,工程前期2012 – scsimon

+0

@scsimon感謝好的解決方案,純偶然的運氣,它支持預2012。說實話,我從來沒有考慮過這個。 :) –

0

您可以使用類似下面。 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 

See working demo

相關問題