如何计算SQL中开始日期和结束日期之间的天数?
ID | START | END
1 |2018-1-1 |2018-1-3
2 |2018-1-1 |2018-1-4
3 |2018-1-1 |2018-1-5
理想情况下会返回:
DATE | COUNT
2018-1-1 | 3
2018-1-2 | 3
2018-1-3 | 3
2018-1-4 | 2
2018-1-5 | 1
答案 0 :(得分:0)
类似的方法得到了一个完整的例子:
DECLARE @range TABLE
(
id INT NOT NULL IDENTITY(1,1),
s_date DATETIME NOT NULL,
e_date DATETIME NOT NULL
);
INSERT INTO @range
(s_date, e_date)
VALUES
('2018-1-1','2018-1-3'),
('2018-1-1','2018-1-4'),
('2018-1-1','2018-1-5');
DECLARE @date TABLE
(
date DATETIME NOT NULL
);
INSERT INTO @date
(date)
VALUES
('2018-1-1'), ('2018-1-1'), ('2018-1-1'),
('2018-1-2'), ('2018-1-2'), ('2018-1-2'),
('2018-1-3'), ('2018-1-3'), ('2018-1-3'),
('2018-1-4'), ('2018-1-4'),
('2018-1-5');
SELECT d.date, COUNT(DISTINCT r.id)
FROM @range r
JOIN @date d ON d.date BETWEEN r.s_date AND r.e_date
GROUP BY d.date
答案 1 :(得分:0)
我发布了一个解决方案,用一个简单的生成器填补空白:
MS SQL Server 2017架构设置:
create table d
( ID int, fSTART date, fEND date );
insert into d values
(1, '2018-1-1' ,'2018-1-3'),
(2, '2018-1-1' ,'2018-1-4'),
(3, '2018-1-1' ,'2018-1-5');
查询1 :
;WITH Nbrs_3( n ) AS ( SELECT 1 UNION SELECT 0 ),
Nbrs_2( n ) AS ( SELECT 1 FROM Nbrs_3 n1 CROSS JOIN Nbrs_3 n2 ),
Nbrs_1( n ) AS ( SELECT 1 FROM Nbrs_2 n1 CROSS JOIN Nbrs_2 n2 ),
Nbrs_0( n ) AS ( SELECT 1 FROM Nbrs_1 n1 CROSS JOIN Nbrs_1 n2 ),
Nbrs ( n ) AS ( SELECT 1 FROM Nbrs_0 n1 CROSS JOIN Nbrs_0 n2 ),
ns (n) as (SELECT ROW_NUMBER() OVER (ORDER BY n) FROM Nbrs )
select distinct dateadd( day, n-1,fSTART )
from d inner join ns on dateadd( day, n-1, fSTART ) between fStart and fend
order by 1
<强> Results 强>:
| |
|------------|
| 2018-01-01 |
| 2018-01-02 |
| 2018-01-03 |
| 2018-01-04 |
| 2018-01-05 |
答案 2 :(得分:0)
我使用交叉申请来获得结果:
我假设您想知道该日期在另一个表的开始日期和结束日期之间的次数。
设定:
declare @s table
( ID int, fSTART date, fEND date );
insert into @s values
(1, '2018-1-1' ,'2018-1-3'),
(2, '2018-1-1' ,'2018-1-4'),
(3, '2018-1-1' ,'2018-1-5');
declare @d table
(dte date)
insert into @d
values
('1/1/2018')
,('1/2/2018')
,('1/3/2018')
,('1/4/2018')
,('1/5/2018')
查询:
select d.dte
,ct = sum(case when d.dte between s.fstart and s.fend then 1 else 0 end)
from @d d
cross apply @s s
group by dte
结果:
dte ct
2018-01-01 3
2018-01-02 3
2018-01-03 3
2018-01-04 2
2018-01-05 1