我有一张看起来像这样的表
ID start_dt end_dt
--------------------------
1 1951-12-05 1951-12-21
2 1951-12-19 1951-12-31
3 1957-12-05 1957-12-19
4 1995-12-06 1995-12-20
5 1996-06-24 1996-07-08
6 1997-05-12 1997-05-26
7 1997-10-07 1997-10-21
8 1997-12-25 1998-01-08
9 1998-01-19 1998-02-02
10 1998-08-05 1998-08-19
我想知道start_dt
和end_dt
之间每个日期的包含次数。
从我的例子中,结果集应该看起来像这样
date count
------------------
1951-12-05 1
1951-12-06 1
...
1951-12-19 2
1951-12-20 2
1951-12-21 2
...
1998-08-19 1
最好的方法是什么?
编辑:为了澄清,我需要在日期范围内(start_dt和end_dt之间)至少出现一次的每个日期,以便在我的结果集中获得一行,并且我希望此日期适合的范围数量在它旁边
希望这会有所帮助
答案 0 :(得分:1)
当您需要将2个值(范围)转换为一系列行时,您可以使用数字表格(如果您不熟悉这个想法,请参阅Aaron Bertrand的The SQL Server Numbers Table文章)。
我使用的是更短更简单的数据,但您应该明白这一点。
declare @dates table (id int not null, start_dt date not null, end_dt date not null)
insert @dates values (1, '20160601', '20160603'),
(2, '20160603', '20160605'),
(3, '20160610', '20160612')
;with cte as (
select
row_number() over (order by so1.object_id) - 1 as n
from
sys.objects so1
cross join sys.objects so2
)
select
dateadd(d, c.n, d.start_dt) as [date],
count(*)
from
@dates d
join cte c on dateadd(d, c.n, d.start_dt) <= d.end_dt
group by
dateadd(d, c.n, d.start_dt)
order by
dateadd(d, c.n, d.start_dt)
答案 1 :(得分:0)
您可以使用CTE
WITH CTE AS(SELECT start_dt AS dates FROM Table
UNION ALL
SELECT end_dt AS dates FROM Table)
SELECT CAST(dates as DATE) as Date, COUNT(dates) AS Count
FROM CTE c
GROUP BY c.dates
order by Count desc
如果您的列属于DATETIME
数据类型,或许您需要更广泛的内容。这种方式将GROUP BY
整天:
WITH CTE AS(SELECT CAST(start_dt AS DATE) AS dates FROM Table
UNION ALL
SELECT CAST(end_dt AS DATE) AS dates FROM Table)
SELECT Dates as Date, COUNT(Dates) AS Count
FROM CTE c
GROUP BY c.dates
order by Count desc
答案 2 :(得分:0)
如果在sys.objects
和start_dt
之间不超过几天(<80左右,具体取决于end_dt
表),您可以使用此方法(受到启发)里斯&#39;。)
DECLARE @dates TABLE (id int not null, start_dt date not null, end_dt date not null)
INSERT @dates VALUES
(1, '1951-12-05', '1951-12-21'),
(2, '1951-12-19', '1951-12-31'),
(3, '1957-12-05', '1957-12-19'),
(4, '1995-12-06', '1995-12-20'),
(5, '1996-06-24', '1996-07-08'),
(6, '1997-05-12', '1997-05-26'),
(7, '1997-10-07', '1997-10-21'),
(8, '1997-12-25', '1998-01-08'),
(9, '1998-01-19', '1998-02-02'),
(10, '1998-08-05', '1998-08-19');
WITH RawData AS (
SELECT
DATEADD(d, n.n, d.start_dt) AS [date]
FROM @dates d
INNER JOIN (
SELECT ROW_NUMBER() OVER (ORDER BY object_id) - 1 AS n FROM sys.objects
) n ON DATEADD(d, n.n, d.start_dt) <= d.end_dt
)
SELECT [date], COUNT(*) [count]
FROM RawData
GROUP BY [date]
ORDER BY [date]
我认为即使有1000个日期范围,这也可能需要很长时间。也许您正在使用包含更多字段的表,甚至缺少某些索引?