简体   繁体   English

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

[英]SQL Server : How to count rows within a given date range?

I have a table:我有一张桌子:

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

I want to generate a second table which indicates, for every day of the year, the number of rows which include that calendar date within the period between the start and end dates, something like this:我想生成第二个表,该表指示一年中的每一天,在开始日期和结束日期之间的时间段内包含该日历日期的行数,如下所示:

WorkDate        NumActive

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

Currently I am trying:目前我正在尝试:

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

This is giving me zeros for every day of the year.这给了我一年中每一天的零。

Any help is appreciated - I'm self-taught via StackOverflow and I'm a bit over my head here.感谢任何帮助 - 我是通过 StackOverflow 自学的,在这里我有点不知所措。

This will give you a count of all the distinct StartDate's that are in the table.这将为您提供表中所有不同 StartDate 的计数。 Copy it to do the same for EndDate.复制它以对 EndDate 执行相同的操作。 Since StartDate and EndDate can be different, I am not sure what your real intention is for counting a date range ?由于 StartDate 和 EndDate 可能不同,我不确定您计算日期范围的真正意图是什么? Does that mean it would be a +1 for every day in the range ?这是否意味着该范围内的每一天都是 +1? Clarify please.请澄清。

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

This will give you the result.这会给你结果。 Assume #cal as TableOne假设 #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

If you want to test, use below queries:如果要测试,请使用以下查询:

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')

Result结果

+-------------------------+-----------+
|        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 |
+-------------------------+-----------+

Please "Mark as Answer" if a post has answered the question如果帖子已经回答了问题,请“标记为答案”

Your where clause having wrong condition.您的 where 子句条件错误。 Please see my inline comments请看我的内嵌评论

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

try this,尝试这个,

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM