提问人:hendra sps 提问时间:9/21/2023 最后编辑:Dale Khendra sps 更新时间:9/21/2023 访问量:58
基于日期范围的 SQL 查询
SQL query based on date range
问:
我有桌子
emp_id | date_time |
---|---|
E001系列 | 23-01-01 07:08 |
E001系列 | 23-01-01 16:07 |
E001系列 | 23-01-03 07:45 |
E001系列 | 23-01-03 16:01 |
我想查询以显示基于日期范围的结果。例如,我将 e001 的日期范围从 23-01-01 设置为 23-01-03,则结果为:
日期 | 在 | 外 |
---|---|---|
23-01-01 | 07:08 | 16:07 |
23-01-02 | 零 | 零 |
23-01-03 | 07:45 | 16:01 |
答:
0赞
Patrick Hurst
9/21/2023
#1
以您的示例数据为例,并将其转换为一些 DDL/DML(这是您在提出这些类型的问题时应该做的非常有用的第一步):
DECLARE @Table TABLE (emp_id VARCHAR(4), date_time DATETIME);
INSERT INTO @Table (emp_id, date_time) VALUES
('e001', '2023-01-01 07:08'),
('e001', '2023-01-01 16:07'),
('e001', '2023-01-03 07:45'),
('e001', '2023-01-03 16:01');
这成为数据外推的简单练习,以确保每个间隔都有行。我们可以简单地使用 .然后,从完整数据集联接回表的聚合(假设您只希望第一个日期时间作为 IN,最后一个日期时间作为 OUT,它们不匹配)。CTE
最后,只需应用谓词来限制日期范围:
;WITH Dates AS (
SELECT MIN(CAST(date_time AS DATE)) AS mnDate, MAX(CAST(date_time AS DATE)) AS mxDate FROM @Table
UNION ALL
SELECT DATEADD(DAY,1,mnDate), mxDate
FROM Dates
WHERE mnDate < mxDate
)
SELECT mnDate AS Date, InDateTime, OutDateTime
FROM Dates d
LEFT OUTER JOIN (
SELECT CAST(date_time AS DATE) AS date, MIN(date_time) AS InDateTime, NULLIF(MAX(date_time),MIN(date_time)) AS OutDateTime
FROM @Table
GROUP BY CAST(date_time AS DATE)
) a
ON d.mnDate = a.date
WHERE d.mnDate BETWEEN '2023-01-01' AND '2023-01-03';
日期 | InDateTime(日期时间) | OutDateTime(OutDateTime) |
---|---|---|
2023-01-01 | 2023-01-01 07:08:00.000 | 2023-01-01 16:07:00.000 |
2023-01-02 | ||
2023-01-03 | 2023-01-03 07:45:00.000 | 2023-01-03 16:01:00.000 |
评论
0赞
Thom A
9/21/2023
希望 OP 正在处理较小的日期范围。如果没有,则理货或预先存在的日历表将是 rCTE 的性能更高的解决方案
2赞
Patrick Hurst
9/21/2023
跨越两年的 rCTE 将少于 800 行,即使在我笨拙的笔记本电脑上也能执行亚秒级。当然,如果将数据集扩展到企业规模,则需要考虑调优和性能选项,但我认为这可能超出了问题的范围。
评论
MIN
MAX