我想知道如何使用循环来填充缺省日期,其值为零,基于sql中组的开始/结束日期,以便我在每个组中都有连续的时间序列。我有两个问题。
我的输入和预期输出如下所示。
输入:我有一张表A,如
date value grp_no
8/06/12 1 1
8/08/12 1 1
8/09/12 0 1
8/07/12 2 2
8/08/12 1 2
8/12/12 3 2
此外,我还有一张表B,可用于与A联系以填补缺少的日期。
date
...
8/05/12
8/06/12
8/07/12
8/08/12
8/09/12
8/10/12
8/11/12
8/12/12
8/13/12
...
如何使用A和B在sql中生成以下输出?
输出:
date value grp_no
8/06/12 1 1
8/07/12 0 1
8/08/12 1 1
8/09/12 0 1
8/07/12 2 2
8/08/12 1 2
8/09/12 0 2
8/10/12 0 2
8/11/12 0 2
8/12/12 3 2
请将您的代码和建议发给我。非常感谢你提前!!!
答案 0 :(得分:12)
你可以这样做,没有循环
SELECT p.date, COALESCE(a.value, 0) value, p.grp_no
FROM
(
SELECT grp_no, date
FROM
(
SELECT grp_no, MIN(date) min_date, MAX(date) max_date
FROM tableA
GROUP BY grp_no
) q CROSS JOIN tableb b
WHERE b.date BETWEEN q.min_date AND q.max_date
) p LEFT JOIN TableA a
ON p.grp_no = a.grp_no
AND p.date = a.date
最里面的子查询每组抓取最小和最大日期。然后与TableB
交叉连接,在每组的最小 - 最大范围内生成所有可能的日期。最后,外部选择使用TableA
的外部联接,并使用value
填充0
列,以填充TableA
中缺少的日期。
输出:
| DATE | VALUE | GRP_NO | |------------|-------|--------| | 2012-08-06 | 1 | 1 | | 2012-08-07 | 0 | 1 | | 2012-08-08 | 1 | 1 | | 2012-08-09 | 0 | 1 | | 2012-08-07 | 2 | 2 | | 2012-08-08 | 1 | 2 | | 2012-08-09 | 0 | 2 | | 2012-08-10 | 0 | 2 | | 2012-08-11 | 0 | 2 | | 2012-08-12 | 3 | 2 |
这是 SQLFiddle 演示
答案 1 :(得分:0)
以下查询对union
和tableA
执行tableB
。然后,它使用分组依据合并来自tableA
和tableB
的行,以便将来自tableB
的所有日期都包含在结果中。如果日期不在tableA
中,则该行的value
和grp_no
具有0。否则,该行将具有value
和grp_no
的实际值。
select
dat,
sum(val),
sum(grp)
from
(
select
date as dat,
value as val,
grp_no as grp
from
tableA
union
select
date,
0,
0
from
tableB
where
date >= date '2012-08-06' and
date <= date '2012-08-13'
)
group by
dat
order by
dat
如果发现此查询对我来说更容易理解。它也运行得更快。这需要16秒,而类似的right join
查询则需要32秒。
此解决方案仅适用于数字数据。
此解决方案假定使用固定的日期范围。通过一些额外的工作,可以将该查询修改为将日期范围限制为tableA
中的内容。
答案 2 :(得分:0)
我只需要查询返回我想要的时间段内的所有日期。没有连接。我想我会与那些想要将它们放在您的查询中的人分享。只需将 365 更改为您想要的任何时间范围即可。
DECLARE @s DATE = GETDATE()-365, @e DATE = GETDATE();
SELECT TOP (DATEDIFF(DAY, @s, @e)+1)
DATEADD(DAY, ROW_NUMBER() OVER (ORDER BY number)-1, @s)
FROM [master].dbo.spt_values
WHERE [type] = N'P' ORDER BY number