我有一个带有以下结构和数据的SQL Server表:
Created , keyword
'2017-10-03 19:18:00', 'test7'
'2017-10-07 01:06:00', 'test3'
'2017-10-07 15:19:00', 'test2'
'2017-10-07 21:39:00', 'test10'
'2017-10-08 00:36:00', 'test3'
'2017-10-08 01:26:00', 'test13'
'2017-10-08 01:33:00', 'test9'
'2017-10-08 08:23:00', 'test13'
'2017-10-08 09:35:00', 'test9'
'2017-10-08 12:38:00', 'test9'
'2017-10-08 15:07:00', 'test2'
'2017-10-10 05:09:00', 'test4'
我想运行一个计算活动的查询并按天分组,也计算没有记录任何内容的天数,并将这些天的活动显示为零。因此,我想要一个将返回以下结果集的查询:
'2017-10-03', 1
'2017-10-04', 0
'2017-10-05', 0
'2017-10-06', 0
'2017-10-07', 3
'2017-10-08', 7
'2017-10-09', 0
'2017-10-03', 1
我知道如何运行查询并将其按天数分组,但不知道如何记录未记录的天数。因为我是Sql的新手,如果有人可以提供一个有效的例子,我将非常感激。提前致谢
答案 0 :(得分:2)
试试这个:
declare @startDate date = '2017-10-01'
declare @endDate date = '2017-10-31'
;with cte as (
select cast(@startDate as date) [dayOfYear]
union all
select DATEADD(day, 1, [dayOfYear]) from cte
where [dayOfYear] < @endDate
)
select dayOfYear, SUM(case when Created is null then 0 else 1 end) from cte
left join MY_TABLE [T] on cte.dayOfYear = CAST(T.Created as date)
group by dayOfYear
逻辑如下:
获取@startDate
和@endDate
之间所有日期的表格(CTE - 我指定的是10月的第一个和最后一个)。然后我们离开加入你的表,当天没有匹配时,我们将相应的值定义为0,否则为1。然后它足以在一天之内总结这些价值。
答案 1 :(得分:0)
declare @date int
WITH CTE_DatesTable
AS
(
SELECT CAST('20171003' as date) AS [date]
UNION ALL
SELECT DATEADD(dd, 1, [date])
FROM CTE_DatesTable
WHERE DATEADD(dd, 1, [date]) <= '20171010'
)
SELECT [CalendarDate]=[date] into #DimDate FROM CTE_DatesTable
OPTION (MAXRECURSION 0);
select * from #DimDate
这将创建一个日历表以与当前表连接以填补空白
答案 2 :(得分:0)
当您没有日历表时,这是一个解决方案:
select row_number() over(order by getdate()) - 1 as n
into #nums
from sys.columns cross join sys.columns c2;
declare @t table(Created datetime, keyword varchar(100));
insert into @t values
('2017-10-03 19:18:00', 'test7'),
('2017-10-07 01:06:00', 'test3'),
('2017-10-07 15:19:00', 'test2'),
('2017-10-07 21:39:00', 'test10'),
('2017-10-08 00:36:00', 'test3'),
('2017-10-08 01:26:00', 'test13'),
('2017-10-08 01:33:00', 'test9'),
('2017-10-08 08:23:00', 'test13'),
('2017-10-08 09:35:00', 'test9'),
('2017-10-08 12:38:00', 'test9'),
('2017-10-08 15:07:00', 'test2'),
('2017-10-10 05:09:00', 'test4')
declare @min_dt date, @max_dt date;
select @min_dt = min(Created), @max_dt = max(Created)
from @t;
with calendar as
(
select dateadd(day, n, @min_dt) as dt
from #nums
where dateadd(day, n, @min_dt) <= @max_dt
)
select c.dt, isnull(count(t.keyword), 0) as cnt
from calendar c left join @t t
on c.dt = cast(t.Created as date)
group by c.dt;
在我的情况下,我没有桌面日历,但我有固定的数字表(Nums),但是如果你没有数字表,你可以像在#nums中那样生成它(您应该将生成的数字限制为合理的数字)