我有下表
table event(
start_tstamp [datetime],
stop_tstamp [datetime],
exe_name [nvarchar](50),
machine_name [nvarchar](30)
)
我需要从这个表生成一个标量表,其中包含以下形式的 start_tstamp 和 stop_tstamp 之间每小时差异的一行信息:
table event_temp(
day_occured [datetime],
hour_occured [tinyint],
exe_name [nvarchar](50),
machine_name [nvarchar](30)
)
例如表事件包含两行
"2012/12/10 07:00", "2012/12/10 09:00", "notepad.exe", "testmachine"
"2012/12/11 15:00", "2012/12/11 18:00", "notepad.exe", "foomachine"
结果 event_temp 应为以下
"2012/12/10 00:00", 7, "notepad.exe", "testmachine"
"2012/12/10 00:00", 8, "notepad.exe", "testmachine"
"2012/12/10 00:00", 9, "notepad.exe", "testmachine"
"2012/12/11 00:00", 15, "notepad.exe", "foomachine"
"2012/12/11 00:00", 16, "notepad.exe", "foomachine"
"2012/12/11 00:00", 17, "notepad.exe", "foomachine"
"2012/12/11 00:00", 18, "notepad.exe", "foomachine"
然后我需要将 event_temp 表与现有的日历表一起加入,该日历表返回与 event_temp
中的日期匹配的日期列表table calendar(
day_occured [datetime],
hour_occured [tinyint],
)
那只会包含:
"2012/12/10 00:00", 0
"2012/12/10 00:00", 1
"2012/12/10 00:00", 2
"2012/12/10 00:00", 3
"2012/12/10 00:00", 4
"2012/12/10 00:00", 5
...
结果应该基本上是一个记录在特定时间内运行的记事本实例的列表。
table result(
day_occured [datetime],
hour_occured [tinyint],
instances_running [int]
)
任何想法如何实现这一目标?
答案 0 :(得分:1)
不包括零小时......
DECLARE @MinDate datetime = (SELECT TOP 1 start_tstamp FROM [event] ORDER BY start_tstamp ASC)
DECLARE @MaxDate datetime = (SELECT TOP 1 stop_tstamp FROM [event] ORDER BY stop_tstamp DESC)
WITH Dates AS (
SELECT @MinDate AS dt
UNION ALL
SELECT DATEADD(hh, 1, dt)
FROM Dates s
WHERE DATEADD(hh, 1, dt) <= @MaxDate)
SELECT
CONVERT(date,d.dt,101) AS [day_occured],
DATEPART(hh, d.dt) AS [hour_occured],
COUNT(*) AS [instances_running]
FROM @Event e
JOIN Dates d ON e.start_tstamp <= d.dt
AND e.stop_tstamp > = d.dt
GROUP BY d.dt
OPTION (MAXRECURSION 0)
包括零小时......
SET @MinDate = CONVERT(date,@MinDate,101)
SET @MaxDate = CONVERT(date, DATEADD(dd,1,@MaxDate))
SET @MaxDate = DATEADD(MILLISECOND, -2,@MaxDate)
SELECT
CONVERT(date,d.dt,101) AS [day_occured],
DATEPART(hh, d.dt) AS [hour_occured],
SUM(CASE ISNULL(exe_name,'-1') WHEN '-1' THEN 0 ELSE 1 END ) AS [instances_running]
FROM [event] e
FULL JOIN Dates d ON e.start_tstamp <= d.dt
AND e.stop_tstamp >= d.dt
GROUP BY d.dt
OPTION (MAXRECURSION 0)