我正在做一个PIVOT命令。我的行标签是日期字段。我的列是[NY],[TX]等位置。源数据中的某些值为空,但是一旦它被转动,我想用日期顺序“填充”那些具有最后已知值的空值。
即如果列NY的值为1/1/2010但是为1/2/2010的值我想要填写从2010年1月1日到1/2/2010的值,以及任何其他的空日期下面直到另一个值已存在。所以基本上我用填充日期的相同数据填充空缺口,每个列都有数据。
我目前的透视查询示例是:
SELECT ReadingDate, [NY],[TX],[WI]
FROM
(SELECT NAME As 'NodeName',
CAST(FORMAT(readingdate, 'M/d/yyyy') as Date) As 'ReadingDate',
SUM(myvalue) As 'Value'
FROM MyTable) as SourceData
PIVOT (SUM(Value) FOR NodeName IN ([NY],[TX],[WI])) as PivotTable
Order BY ReadingDate
但我不知道怎么做这个“填充”来填补空值
示例源数据
1/1/2010, TX, 1
1/1/2010, NY, 5
1/2/2010, NY null
1/1/2010, WI, 3
1/3/2010, WI, 7
...
注意1/2和NY的1/3没有WI会导致枢轴结果中出现空值。还有一个空记录也导致null。对于NY,一旦转动1/2需要用5来填充,因为它是最后已知的值,但是1/3也需要一次转动5,因为该记录甚至不存在但是当转动时它会显示出来作为空值,因为它不存在,但另一个位置有记录。
答案 0 :(得分:1)
这可能是SQL Server的痛苦。 ANSI支持LAG()
上的一个很好的功能,称为IGNORE NULL
,但SQL Server还没有支持它。我将从使用条件聚合(个人偏好)开始:
select cast(readingdate as date) as readingdate,,
sum(case when name = 'NY' then value end) as NY,
sum(case when name = 'TX' then value end) as TX,
sum(case when name = 'WI' then value end) as WI
from mytable
group by cast(readingdate as date);
所以,我们必须更聪明一点。我们可以根据它们之前的非NULL值的数量将NULL
值分配到组中。幸运的是,使用累积COUNT()
函数很容易做到这一点。然后,我们可以使用MAX()
(或MIN()
)获取此组中的一个非NULL值:
with t as (
select cast(readingdate as date) as readingdate,
sum(case when name = 'NY' then value end) as NY,
sum(case when name = 'TX' then value end) as TX,
sum(case when name = 'WI' then value end) as WI,
from mytable
group by cast(readingdate as date)
),
t2 as (
select t.*,
count(NY) over (order by readingdate) as NYgrp,
count(TX) over (order by readingdate) as TXgrp,
count(WI) over (order by readingdate) as WIgrp
from t
)
select readingdate,
coalesce(NY, max(NY) over (partition by NYgrp)) as NY,
coalesce(TX, max(TX) over (partition by TXgrp)) as TX,
coalesce(WI, max(WI) over (partition by WIgrp)) as WI
from t2;