用零填充SQL查询中的日期间隔
我有下面的结构,它来自于表之间的一些连接,等等,这些连接将用于生成图表 有些ID没有所有日期的数据,这导致图表中出现一些虚线 问题是,如何为每个ID添加缺少的日期,并用零填充其数据单元格 作为脚本:用零填充SQL查询中的日期间隔,sql,sql-server,tsql,Sql,Sql Server,Tsql,我有下面的结构,它来自于表之间的一些连接,等等,这些连接将用于生成图表 有些ID没有所有日期的数据,这导致图表中出现一些虚线 问题是,如何为每个ID添加缺少的日期,并用零填充其数据单元格 作为脚本: (67, '2016-09-28 00:00:00.000',1), (178, '2016-09-28 00:00:00.000',6), (42, '2016-09-25 00:00:00.000',1), (66, '2016-09-25 00:00:00.000',122), (67, '2
(67, '2016-09-28 00:00:00.000',1),
(178, '2016-09-28 00:00:00.000',6),
(42, '2016-09-25 00:00:00.000',1),
(66, '2016-09-25 00:00:00.000',122),
(67, '2016-09-25 00:00:00.000',2),
(10, '2016-09-24 00:00:00.000',5),
(13, '2016-09-24 00:00:00.000',4),
(66, '2016-09-24 00:00:00.000',198),
(67, '2016-09-24 00:00:00.000',15),
(178, '2016-09-24 00:00:00.000',4),
(10, '2016-09-23 00:00:00.000',1),
(13, '2016-09-23 00:00:00.000',2),
(42, '2016-09-23 00:00:00.000',4),
(66, '2016-09-23 00:00:00.000',208),
(67, '2016-09-23 00:00:00.000',15)
这里有一种方法:
with t as (
<your query here>
)
select i.id, rt.roundedtime, coalesce(data, 0) as data
from (select distinct id from t) i cross join
(select distinct roundedtime rt from t) rt left join
t
on t.id = i.id and t.roundedtime = rt.roundedtime;
换句话说,使用交叉连接创建日期和ID的列表。然后使用左连接来引入数据
此查询在原始数据上使用select distinct来获取日期和ID的列表。获取这些列表可能有更有效的方法。您可以在使用join的SELECT语句中选中ISNULLYourDataColumn,0
例如:
在上面的Select语句数据列中,如果联接后没有可用数据,则返回0
;WITH YourQueryOutput AS (
--put your select statement here
), calendar AS (
SELECT CAST(MIN(RoundedTime) as datetime) as d,
MAX(RoundedTime) as e
FROM YourQueryOutput
UNION ALL
SELECT DATEADD(day,1,d),
e
FROM calendar
WHERE d < e
)
SELECT t.ID,
c.d,
COALESCE(t1.[data],0) as [data]
FROM calendar c
CROSS JOIN (
SELECT DISTINCT ID
FROM YourQueryOutput
) t
LEFT JOIN YourQueryOutput t1
ON t.ID = t1.ID and t1.RoundedTime = c.d
ORDER BY t.ID, c.d
OPTION(MAXRECURSION 0)
我认为您需要使用某种日历表。@JohnHC的可能重复项我无法可视化数据结构,因此无法确定这是否是重复项,因为据我所知,有一些ID未包含在该查询中,OP需要用缺失的日期和零来显示它们。据我所知,在输出表中,没有针对某个日期的数据,所以图表呈现不正确,所以应该有一些数据,如果图表接受int,那么其他值为0,根据数据type@gofr1:没错,该查询中的ID和RoundedTime都有间隙,所以ISNULL在这里不会有太大作用,谢谢你的反馈。问题是并不是所有的日期都列出了,所以它们不会显示在您的查询中
;WITH YourQueryOutput AS (
--put your select statement here
), calendar AS (
SELECT CAST(MIN(RoundedTime) as datetime) as d,
MAX(RoundedTime) as e
FROM YourQueryOutput
UNION ALL
SELECT DATEADD(day,1,d),
e
FROM calendar
WHERE d < e
)
SELECT t.ID,
c.d,
COALESCE(t1.[data],0) as [data]
FROM calendar c
CROSS JOIN (
SELECT DISTINCT ID
FROM YourQueryOutput
) t
LEFT JOIN YourQueryOutput t1
ON t.ID = t1.ID and t1.RoundedTime = c.d
ORDER BY t.ID, c.d
OPTION(MAXRECURSION 0)
ID d data
10 2016-09-23 00:00:00.000 1
10 2016-09-24 00:00:00.000 5
10 2016-09-25 00:00:00.000 0
10 2016-09-26 00:00:00.000 0
10 2016-09-27 00:00:00.000 0
10 2016-09-28 00:00:00.000 0
...
178 2016-09-23 00:00:00.000 0
178 2016-09-24 00:00:00.000 4
178 2016-09-25 00:00:00.000 0
178 2016-09-26 00:00:00.000 0
178 2016-09-27 00:00:00.000 0
178 2016-09-28 00:00:00.000 6