【发布时间】:2018-04-13 18:09:15
【问题描述】:
我什至不确定这是否可以/应该通过 SQL 来完成,但可以。
我有一个像这样存储开始日期和结束日期的表格
userPingId createdAt lastUpdatedAt
1 2017-10-17 11:31:52.160 2017-10-18 14:31:52.160
我想返回一个按日期对结果进行分组的结果集,以及它们是否在两个日期之间的不同点之间处于活动状态。
不同点是
- 早上 - 中午 12 点之前
- 下午 - 中午 12 点到下午 5 点之间
- 晚上 - 下午 5 点之后
所以例如我会得到以下结果
sessionDate morning afternoon evening
2017-10-17 1 1 1
2017-10-18 1 1 0
这是我到目前为止所拥有的,我相信它非常接近,但我无法获得我需要的结果这一事实让我认为这在 SQL 中可能是不可能的(顺便说一句,我正在使用数字查找表在我在另一个教程中看到的查询中)
DECLARE @s DATE = '2017-01-01', @e DATE = '2018-01-01';
;WITH d(sessionDate) AS
(
SELECT TOP (DATEDIFF(DAY, @s, @e) + 1) DATEADD(DAY, n-1, @s)
FROM dbo.Numbers ORDER BY n
)
SELECT
d.sessionDate,
sum(case when
(CONVERT(DATE, createdAt) = d.sessionDate AND datepart(hour, createdAt) < 12)
OR (CONVERT(DATE, lastUpdatedAt) = d.sessionDate AND datepart(hour, lastUpdatedAt) < 12)
then 1 else 0 end) as Morning,
sum(case when
(datepart(hour, createdAt) >= 12 and datepart(hour, createdAt) < 17)
OR (datepart(hour, lastUpdatedAt) >= 12 and datepart(hour, lastUpdatedAt) < 17)
OR (datepart(hour, createdAt) < 12 and datepart(hour, lastUpdatedAt) >= 17)
then 1 else 0 end) as Afternoon,
sum(case when datepart(hour, createdAt) >= 17 OR datepart(hour, lastUpdatedAt) >= 17 then 1 else 0 end) as Evening
FROM d
LEFT OUTER JOIN MYTABLE AS s
ON s.createdAt >= @s AND s.lastUpdatedAt <= @e
AND (CONVERT(DATE, s.createdAt) = d.sessionDate OR CONVERT(DATE, s.lastUpdatedAt) = d.sessionDate)
WHERE d.sessionDate >= @s AND d.sessionDate <= @e
AND userPingId = 49
GROUP BY d.sessionDate
ORDER BY d.sessionDate;
【问题讨论】:
-
你使用的是什么版本的sql server?时间数据类型 (stackoverflow.com/a/3656549/359135) 和数据透视命令的组合可以让这变得非常简单 (data.stackexchange.com/stackoverflow/revision/749735/930554/…)
-
createdAt到lastUpdatedAt可以只跨越一天或两天(午夜之前到午夜之后)甚至更多天吗? -
我相信我们使用的是最新版本的 SQL Server,并且 createdAt 到 lastUpdatedAt 可以跨越任意天数
-
给你:Microsoft SQL Server 2016 (RTM-CU2) (KB3182270) - 13.0.2164.0 (X64)
-
@gordatron 在这种情况下,我希望它出现在第一天的上午、下午和晚上以及第二天的上午和下午。所以我猜这两个日期之间的所有连续时间段(早上、下午和晚上)
标签: sql sql-server datetime