如何从多列中检索"最后"非零值?

Rob*_*ert 5 sql t-sql sql-server sql-server-2012

考虑一个有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
Run Code Online (Sandbox Code Playgroud)

我需要一个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
Run Code Online (Sandbox Code Playgroud)

Subquery中可以找到类似的问题:如何从列中检索最后一个非零值?但它只适用于一列,并且包含更多列的泛化(如本例所示)似乎不实用.

Gor*_*off 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;
Run Code Online (Sandbox Code Playgroud)

一般来说,我反对使用select distinct它来替代聚合查询。不幸的是,SQL Server 支持first_value()窗口函数,但不提供等效的聚合功能。

注意:该sign()函数用于将零值放在最后。如果可以有负值,则使用abs(sign())