Tsql 使用SQL Server 2012的最后一个_Value()函数时忽略空值

Tsql 使用SQL Server 2012的最后一个_Value()函数时忽略空值,tsql,sql-server-2012,Tsql,Sql Server 2012,我使用的是SQL Server 2012,它有一个如下所示的值表。它由事件数据填充 FldType Date Price Size -------------------------------------------- 2 2012-08-22 00:02:01 9140 1048 0 2012-08-22 00:02:02 9140 77 1 2012-08-22 00:02:03

我使用的是SQL Server 2012,它有一个如下所示的值表。它由事件数据填充

FldType Date                    Price   Size
--------------------------------------------
2       2012-08-22 00:02:01     9140    1048
0       2012-08-22 00:02:02     9140    77
1       2012-08-22 00:02:03     9150    281
2       2012-08-22 00:02:04     9140    1090
0       2012-08-22 00:02:05     9150    1
1       2012-08-22 00:02:06     9150    324
2       2012-08-22 00:02:07     9140    1063
我希望跟踪3种字段类型0、1、2的最新值,以便最终输出如下所示

Date                Price0  Size0   Price1  Size1   Price2  Size2
-----------------------------------------------------------------
2012-08-22 00:02:01  NULL   NULL    NULL    NULL    9140    1048
2012-08-22 00:02:02  9140   77      NULL    NULL    9140    1048
2012-08-22 00:02:03  9140   77      9150    281     9140    1048
2012-08-22 00:02:04  9140   77      9150    281     9140    1090
2012-08-22 00:02:05  9150   1       9150    281     9140    1090
2012-08-22 00:02:06  9150   1       9150    324     9140    1090
2012-08-22 00:02:07  9150   1       9150    324     9140    1063
不幸的是,它并没有忽略后续的空值,所以我得到了这个值

Date                Price0  Size0   Price1  Size1   Price2  Size2
-----------------------------------------------------------------
2012-08-22 00:02:01  NULL   NULL    NULL    NULL    9140    1048
2012-08-22 00:02:02  9140   77      NULL    NULL    NULL    NULL    
2012-08-22 00:02:03  NULL   NULL    9150    281     NULL    NULL
2012-08-22 00:02:04  NULL   NULL    NULL    NULL    9140    1090
2012-08-22 00:02:05  9150   1       NULL    NULL    NULL    NULL    
2012-08-22 00:02:06  NULL   NULL    9150    324     NULL    NULL    
2012-08-22 00:02:07  NULL   NULL    NULL    NULL    9140    1063
我当前的查询如下所示

SELECT [Date],
    LAST_VALUE(Price0) OVER (PARTITION BY FldType ORDER BY [Date] ) AS Price0,
    LAST_VALUE(Size0) OVER (PARTITION BY FldType ORDER BY [Date]) AS Size0,
    LAST_VALUE(Price1) OVER (PARTITION BY FldType ORDER BY [Date] ) AS Price1,
    LAST_VALUE(Size1) OVER (PARTITION BY FldType ORDER BY [Date]) AS Size1,
    LAST_VALUE(Price2) OVER (PARTITION BY FldType ORDER BY [Date] ) AS Price2,
    LAST_VALUE(Size2) OVER (PARTITION BY FldType ORDER BY [Date]) AS Size2
FROM ( 
SELECT FldType, [Date], Price, Size,
    CASE WHEN FldType = 0 THEN Price END as Price0,
    CASE WHEN FldType = 0 THEN Size END as Size0,
    CASE WHEN FldType = 1 THEN Price END as Price1,
    CASE WHEN FldType = 1 THEN Size END as Size1,
    CASE WHEN FldType = 2 THEN Price END as Price2,
    CASE WHEN FldType = 2 THEN Size END as Size2
FROM [RawData].[dbo].[Events]   
) as T1
ORDER BY [Date]
在确定最新值时,是否有办法让SQL Server 2012忽略空值?或者有没有更好的方法不使用最后一个值函数

总而言之,我正在努力实现两件事

将价格和大小列拆分为6列2列x 3字段类型 跟踪每列中的最新值。
如果您有任何建议,我们将不胜感激。

我不确定您是否可以使用LAST_值执行此操作,除非您添加一个轴

此外,您需要分别对待大小和价格,因为它们来自不同的行。所以,这就实现了你想要的,分解它

DECLARE @source TABLE (FldType int, DateCol DateTime, Price int, Size int);

INSERT @source VALUES
    (2, '2012-08-22 00:02:01', 9140, 1048),(0, '2012-08-22 00:02:02', 9140, 77),
    (1, '2012-08-22 00:02:03', 9150, 281),(2, '2012-08-22 00:02:04', 9140, 1090),
    (0, '2012-08-22 00:02:05', 9150, 1),(1, '2012-08-22 00:02:06', 9150, 324),
    (2, '2012-08-22 00:02:07', 9140, 1063);


SELECT
    S.DateCol, Xp0.Price0, Xs0.Size0, Xp1.Price1, Xs1.Size1, Xp2.Price2, Xs2.Size2
FROM
    @source S
    OUTER APPLY
    (SELECT TOP 1 S0.Price AS Price0 FROM @source S0 WHERE S0.FldType = 0 AND S0.DateCol <= S.DateCol ORDER BY S0.DateCol DESC) Xp0
    OUTER APPLY
    (SELECT TOP 1 S1.Price AS Price1 FROM @source S1 WHERE S1.FldType = 1 AND S1.DateCol <= S.DateCol ORDER BY S1.DateCol DESC) Xp1
    OUTER APPLY
    (SELECT TOP 1 S2.Price AS Price2 FROM @source S2 WHERE S2.FldType = 2 AND S2.DateCol <= S.DateCol ORDER BY S2.DateCol DESC) Xp2
    OUTER APPLY
    (SELECT TOP 1 S0.Size AS Size0 FROM @source S0 WHERE S0.FldType = 0 AND S0.DateCol <= S.DateCol ORDER BY S0.DateCol DESC) Xs0
    OUTER APPLY
    (SELECT TOP 1 S1.Size AS Size1 FROM @source S1 WHERE S1.FldType = 1 AND S1.DateCol <= S.DateCol ORDER BY S1.DateCol DESC) Xs1
    OUTER APPLY
    (SELECT TOP 1 S2.Size AS Size2 FROM @source S2 WHERE S2.FldType = 2 AND S2.DateCol <= S.DateCol ORDER BY S2.DateCol DESC) Xs2
ORDER BY
    DateCol;

另一种方法是通过触发器或一些ETL来维护一个单独的表,以便为您进行汇总。

SQL=structured query language,该语言本身;SQL 2012=SQL语言的2012标准不存在;SQL Server 2012=2012版的Microsoft SQL Serverproduct@marc_S说得好!。谢谢你的改变!编辑标题,以明确它是SQL Server 2012。这是一个重要的区别,因为1 Oracle的SQL确实有一个ignore nulls选项,2在SQL Server 2012中有“ROWS”和“RANGE”选项,它们在寻找解决方案时可能会有一些用处。好吧,堆叠者之间的共识是,您使用的SQL Server的确切版本属于标记,而不是标题……明白了。谢谢你的提示!非常感谢。这确实给了我所需要的。我不知道外部应用方法@ChrisTarn,本质上,您需要带有IGNORE NULL子句的LAST_值,但不幸的是SQL Server并没有实现它,例如Oracle。由于为每一行运行子查询,外部应用方法可能非常昂贵。伊齐克·本·甘在他的演讲中展示了如何更有效地完成这项工作。