我想合并这两个语句以获得7行(每天一行),并告诉我每天有多少事件和警报。如果没有,我想为每一行(日)获得一个“NULL”值。
当前的声明有效,但“事件”和“警报”在不同的行上,如果没有事件,我什么也得不到......
我想我可以使用“WITH”子句,但我有点迷失:S
SELECT 'events' as Type,
CAST(extended_timestamp AS DATE) as DateField,
count(*) as SumField
FROM [dbauditor_repo].[dbo].[dbauditor_repo_events]
WHERE extended_timestamp > (select DATEADD(day, DATEDIFF(day, 0, GETDATE())-7, 0))
GROUP BY CAST(extended_timestamp AS DATE)
UNION
SELECT 'alarms' as Type,
CAST(extended_timestamp AS DATE) as DateField, count(*) as SumField
FROM [dbauditor_repo].[dbo].[dbauditor_repo_events]
WHERE extended_timestamp > (select DATEADD(day, DATEDIFF(day, 0, GETDATE())-7, 0))
AND returncode = 1
GROUP BY CAST(extended_timestamp AS DATE)
ORDER BY DateField
感谢您的帮助!
答案 0 :(得分:0)
不知道表格背后的架构,并假设returncode = 1
表示警报:
SELECT IIF(returncode = 1, 'alarms', 'events') as [Type]
, CAST(extended_timestamp AS DATE) as DateField
, count(*) as SumField
FROM [dbauditor_repo].[dbo].[dbauditor_repo_events]
WHERE extended_timestamp > DATEADD(day, DATEDIFF(day, 0, GETDATE())-7, 0)
GROUP BY IIF(returncode = 1, 'alarms', 'events'), CAST(extended_timestamp AS DATE)
ORDER BY DateField
<强>更新强>
道歉,似乎我没有正确地阅读你的问题。您需要的是我上面的原始答案和PIVOT
的组合,以平整结果集并为您提供3列。
CTE几乎相同 - 它采用数据集并计算其Type
。在此之后,我们使用PIVOT
将每个Type的每日计数放入其自己的列中。
declare @events table (ID int, extended_timestamp datetime, returncode int)
insert into @events values (1, dateadd(day, -6, GETDATE()), 0), (2, dateadd(day, -6, GETDATE()), 1), (3, dateadd(day, -6, GETDATE()), 1), (4, dateadd(day, -5, GETDATE()), 1);
WITH CTE AS(
SELECT IIF(returncode = 1, 'alarms', 'events') as [Type]
, DATEDIFF(day, 0, extended_timestamp) as DayNumber
, count(*) as SumField
FROM @events
WHERE extended_timestamp >= DATEADD(day, DATEDIFF(day, 0, GETDATE())-6, 0)
GROUP BY IIF(returncode = 1, 'alarms', 'events'), DATEDIFF(day, 0, extended_timestamp)
)
, CTE2 AS(
select DayNumber, [events] + [alarms] as [events], [alarms]
from
(select SumField, DayNumber, [Type] from CTE) as _S
PIVOT (
SUM(SumField)
FOR [Type] IN ([events], [alarms])
) as _P
)
select cast(DATEADD(day, n.N, 0) as Date) as DateField, [events], [alarms]
from dbo.Numbers n
left outer join CTE2 on n.N = DayNumber
where n.N between DATEDIFF(day, 0, GETDATE()) - 6 and DATEDIFF(day, 0, GETDATE())
order by 1
返回:
DateField events alarms
---------- ----------- -----------
2014-07-31 3 2
2014-08-01 1 1
2014-08-02 NULL NULL
2014-08-03 NULL NULL
2014-08-04 NULL NULL
2014-08-05 NULL NULL
2014-08-06 NULL NULL
这也使用Numbers table来获取“每天1行,无论如何”要求。请注意,查询已更改为使用DayNumber,因此此连接可以尽可能干净。
答案 1 :(得分:0)
在我对我的误解之后做了很多修改之后,发现上面我的答案中的SQL真的很愚蠢。它完成了工作,但一旦正确理解,有一个更清晰的版本:
declare @events table (ID int, extended_timestamp datetime, returncode int)
insert into @events values (1, dateadd(day, -6, GETDATE()), 0), (2, dateadd(day, -6, GETDATE()), 1), (3, dateadd(day, -6, GETDATE()), 1), (4, dateadd(day, -5, GETDATE()), 1);
select cast(DATEADD(day, n.N, 0) as Date) as DateField
, NULLIF(SUM(CASE WHEN returncode IS NOT NULL THEN 1 ELSE 0 END),0) as [events]
, NULLIF(SUM(CASE WHEN returncode = 1 THEN 1 ELSE 0 END),0) as [alarms]
from dbo.Numbers n
left outer join @events on n.N = DATEDIFF(day, 0, extended_timestamp)
where n.N between DATEDIFF(day, 0, GETDATE()) - 6 and DATEDIFF(day, 0, GETDATE())
group by n.N
order by 1
结果完全相同:
DateField events alarms
---------- ----------- -----------
2014-07-31 3 2
2014-08-01 1 1
2014-08-02 NULL NULL
2014-08-03 NULL NULL
2014-08-04 NULL NULL
2014-08-05 NULL NULL
2014-08-06 NULL NULL
答案 2 :(得分:0)
您最初的问题是如何合并到语句或不同的数据集。
答案是你需要找到一些东西来加入它们。 UNION会将结果合并为您发现的单独行。
我认为这会做你想要的,它会在DATE对每个单独的查询进行分组,然后在同一个日期加入以显示你正在寻找的结果。
select a.DateField, a.events, b.alarms FROM
(select CAST(extended_timestamp AS DATE) as DateField, count(*) as [events]
FROM [dbauditor_repo].[dbo].[dbauditor_repo_events]
WHERE extended_timestamp > DATEADD(day,-7, getdate())
GROUP BY CAST(extended_timestamp AS DATE)
) a
,(select CAST(extended_timestamp AS DATE) as DateField, count(*) as [alarms]
FROM [dbauditor_repo].[dbo].[dbauditor_repo_events]
WHERE extended_timestamp > DATEADD(day, -7, getdate()) AND returncode = 1
GROUP BY CAST(extended_timestamp AS DATE)
) b
where a.DateField = b.DateField
ORDER BY a.DateField
但是再一次,在审核了你的陈述后,看起来“闹钟”只是一种事件,所以我认为你可以在你的情况下选择一个选项:
SELECT DateField, max([events]) as [events], max([alarms]) as [alarms] FROM
(select CAST(extended_timestamp AS DATE) as DateField, count(*) as [events],
SUM(case when returncode = 1 as 1 else 0 end) as [alarms]
FROM [dbauditor_repo].[dbo].[dbauditor_repo_events]
WHERE extended_timestamp > DATEADD(day, -7, getdate())
GROUP BY CAST(extended_timestamp AS DATE)
UNION
select CAST(getdate() as DATE), NULL, NULL
UNION
select CAST(DATEADD(day, -1, getdate()) as DATE), NULL, NULL
UNION
select CAST(DATEADD(day, -2, getdate()) as DATE), NULL, NULL
UNION
select CAST(DATEADD(day, -3, getdate()) as DATE), NULL, NULL
UNION
select CAST(DATEADD(day, -4, getdate()) as DATE), NULL, NULL
UNION
select CAST(DATEADD(day, -5, getdate()) as DATE), NULL, NULL
UNION
select CAST(DATEADD(day, -6, getdate()) as DATE), NULL, NULL
) a
GROUP BY DateField
ORDER BY DateField
答案 3 :(得分:0)
根据您当前的查询,当returncode
为1时,事件也可能是警报,因此它会对两个计数产生影响。
此查询将在同一行返回两个计数:
SELECT
x.DateField,
Events = COUNT(*),
Alarms = COUNT(CASE e.returncode WHEN 1 THEN 1 END)
FROM
[dbauditor_repo].[dbo].[dbauditor_repo_events] AS e
CROSS APPLY
(SELECT CAST(e.extended_timestamp AS DATE)) AS x (DateField)
WHERE
e.extended_timestamp > DATEADD(day, DATEDIFF(day, 0, GETDATE())-7, 0)
GROUP BY
x.DateField
;
Alarms
表达式使用条件聚合:它仅在e.returncode
匹配1时计算行数,而Events
只是&#34;计算所有行&#34;。
上述查询的唯一问题是它只返回表中表示的天数。要根据需要返回整个时间间隔的结果集,可以使用如下日历表:
SELECT
DateField = c.Date,
Events = COUNT(*),
Alarms = COUNT(CASE returncode WHEN 1 THEN 1 END)
FROM
[dbauditor_repo].[dbo].[dbauditor_repo_events] AS e
CROSS APPLY
(SELECT CAST(e.extended_timestamp AS DATE)) AS x (DateField)
RIGHT JOIN
dbo.Calendar AS c ON c.Date = x.DateField
AND e.extended_timestamp > DATEADD(day, DATEDIFF(day, 0, GETDATE())-7, 0)
GROUP BY
c.Date
;
如果您没有日历表,可以轻松创建日历表&#34;即时#34;在7天的小时间内,例如使用这种方法:
SELECT
Date = DATEADD(DAY, DayNumber, StartingDate)
FROM
(VALUES (0), (1), (2), (3), (4), (5), (6)) AS v (DayNumber)
CROSS APPLY
(SELECT DATEADD(DAY, -7, CAST(GETDATE() AS date))) AS x (StartingDate)
;
因此,将它与前一个查询相结合,你会得到这样的结果:
WITH Calendar AS (
SELECT
Date = DATEADD(DAY, DayNumber, StartingDate)
FROM
(VALUES (0), (1), (2), (3), (4), (5), (6)) AS v (DayNumber)
CROSS APPLY
(SELECT DATEADD(DAY, -7, CAST(GETDATE() AS date))) AS x (StartingDate)
)
SELECT
DateField = c.Date,
Events = COUNT(*),
Alarms = COUNT(CASE returncode WHEN 1 THEN 1 END)
FROM
[dbauditor_repo].[dbo].[dbauditor_repo_events] AS e
CROSS APPLY
(SELECT CAST(e.extended_timestamp AS DATE)) AS x (DateField)
RIGHT JOIN
Calendar AS c ON c.Date = x.DateField
AND e.extended_timestamp > DATEADD(day, DATEDIFF(day, 0, GETDATE())-7, 0)
GROUP BY
c.Date
;