SQL Server:如何计算给定日期范围内的行?

时间:2016-04-29 23:03:45

标签: sql sql-server

我有一张桌子:

ID     StartDate       EndDate

1      2016-01-01      2016-01-03
2      2016-01-01      2016-01-01
3      2016-01-01      2016-01-01
4      2016-01-02      2016-01-02

我想生成第二个表格,该表格指示一年中的每一天,在开始日期和结束日期之间包含该日历日期的行数,如下所示:

WorkDate        NumActive

2016-01-01      3
2016-01-02      2
2016-01-03      1

目前我正在尝试:

SELECT      COUNT(ID)
FROM        TableOne
WHERE       StartDate   >=  WorkDate
        and EndDate     <=  WorkDate

这给了我一年中每一天的零。

感谢任何帮助 - 我通过StackOverflow自学成才,我在这里有点过头了。

4 个答案:

答案 0 :(得分:1)

这将为您计算表中所有不同的StartDate。 复制它以对EndDate执行相同操作。 由于StartDate和EndDate可能不同,我不确定您计算日期范围的真实意图是什么?这是否意味着该范围内的每一天都是+1?请澄清。

Select
    StartDate
    ,Count(*) over (partition by StartDate) as 'cntStartDates'
From TableOne
Group By StartDate

答案 1 :(得分:0)

这会给你结果。假设#cal为TableOne

;with tal as (
select distinct number from master.dbo.spt_values 
where number between 1 and 365
)
, c2 as (
select DATEADD(d, number - 1, '2016-01-01') dt
from tal
)
select dt AS WorkDate, COUNT(*) AS NumActive
from c2 inner join #cal on c2.dt between #cal.StartDate and #cal.EndDate
group by dt
order by 1

如果您想测试,请使用以下查询:

create table #cal (id int, StartDate date, EndDate date)

insert into #cal values 
(1, '2016-01-01', '2016-01-03'),
(2, '2016-01-01', '2016-01-01'),
(3, '2016-01-01', '2016-01-01'),
(4, '2016-01-02', '2016-01-02')

结果

+-------------------------+-----------+
|        WorkDate         | NumActive |
+-------------------------+-----------+
| 2016-01-01 00:00:00.000 |         3 |
| 2016-01-02 00:00:00.000 |         2 |
| 2016-01-03 00:00:00.000 |         1 |
+-------------------------+-----------+

请&#34;标记为答案&#34;如果帖子已回答问题

答案 2 :(得分:0)

你的where子句有错误的条件。请参阅我的内联评论

CREATE TABLE #TempWorkDate (Id INT, StartDate DATETIME, EndDate DATETIME)
GO

INSERT INTO #TempWorkDate
SELECT 1, DATEADD(D, +1, GETDATE()), DATEADD(D, +4, GETDATE()) UNION ALL
SELECT 1, DATEADD(D, +1, GETDATE()), DATEADD(D, +1, GETDATE()) UNION ALL
SELECT 1, DATEADD(D, +1, GETDATE()), DATEADD(D, +1, GETDATE()) UNION ALL
SELECT 1, DATEADD(D, +2, GETDATE()), DATEADD(D, +2, GETDATE()) 
GO

-- This query won't work, because the condition is wrong
SELECT * FROM #TempWorkDate
WHERE StartDate >= '2016-05-02' AND EndDate <= '2016-05-02'

-- The below query returns the result
SELECT * FROM #TempWorkDate
WHERE StartDate <= '2016-05-02' AND EndDate >= '2016-05-02'

DROP TABLE #TempWorkDate

答案 3 :(得分:0)

试试这个,

declare @cal table (id int, StartDate date, EndDate date)

insert into @cal values 
(1, '2016-01-01', '2016-01-03'),
(2, '2016-01-01', '2016-01-01'),
(3, '2016-01-01', '2016-01-01'),
(4, '2016-01-02', '2016-01-02')

;with t(id,dts) as (select id,startDate from @cal union all 
select t.id,dateadd(day,1,dts) from t join @cal t1 on t.id=t1.id where t.dts<t1.EndDate)

select dts WorkDate,count(dts) NumActive from t group by dts