Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 以天为单位分组_Sql_Sql Server - Fatal编程技术网

Sql 以天为单位分组

Sql 以天为单位分组,sql,sql-server,Sql,Sql Server,我有一个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

我有一个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新手,如果有人能提供一个工作示例,我将不胜感激。提前谢谢

 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
这将创建一个日历表与当前表连接,以填补空白

这将创建一个日历表,以便与当前表连接以填补空白

尝试以下操作:

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
逻辑如下:

获取CTE-I指定的10月1日和10月最后一日@startDate和@endDate之间的所有日期的表格。然后我们离开join表,当天数不匹配时,我们将相应的值定义为0,否则定义为1。然后,每天对这些值求和就足够了。

试试这个:

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
逻辑如下:


获取CTE-I指定的10月1日和10月最后一日@startDate和@endDate之间的所有日期的表格。然后我们离开join表,当天数不匹配时,我们将相应的值定义为0,否则定义为1。然后,每天对这些值求和就足够了。

当您没有日历表时,这里有一个解决方案:

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中一样生成它,您应该将生成的数字限制为合理的数字

当您没有日历表格时,这里有一个解决方案:

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中一样生成它,您应该将生成的数字限制在合理的数字上

最好的解决方案是创建表格日历,将您的表加入此日历表lrft在dt=dt和dt之间加入您的表。。。并对结果进行分组。如果您没有日历表,您可以根据以前使用另一个DBMS的经验快速生成它,我认为没有简单的解决方案。也许最好的方法是循环查询的输出并手动填补空白。谢谢,您可以提供一个示例吗?类似的问题最好的解决方案是创建一个表日历,将您的表连接到此日历表lrft在dt=dt和dt之间连接您的表。。。并对结果进行分组。如果您没有日历表,您可以根据以前使用另一个DBMS的经验快速生成它,我认为没有简单的解决方案。也许最好是循环查询的输出并手动填补空白。谢谢,您可以提供一个示例吗?类似的问题如果您有100多行,则必须添加“OPTION MAXRECURSION 200”。这将阻止:语句终止。在语句完成之前,最大递归100已用尽。如果有100多行,则必须添加“OPTION MAXRECURSION 200”。这将阻止:语句终止。在语句完成之前,已耗尽最大递归100。