我在MSSQL中有一个表,结构如下:
PersonId
StartDate
EndDate
我需要能够在日期范围内或在给定日期显示表格中不同人数。
作为一个例子,我需要每天显示每天的总数,例如如果我们在6月1日有2个条目,6月2日有3个条目,6月3日有1个条目,系统应显示以下结果:
1st June: 2
2nd June: 5
3rd June: 6
但是,例如在6月2日的参赛作品中,结束日期为6月2日,而6月3日的结果仅为5。
是否有人能够协助解决这个问题。
由于
这是我到目前为止似乎有效的方法。有没有更好的解决方案,因为我的解决方案只能让我使用数字。我还需要在另一个专栏上失业 - 失业意味着要么没有参加表格,要么没有参加任何其他参赛作品。
CREATE TABLE #Temp(CountTotal int NOT NULL, CountDate datetime NOT NULL);
DECLARE @StartDT DATETIME
SET @StartDT = '2015-01-01 00:00:00'
WHILE @StartDT < '2015-08-31 00:00:00'
BEGIN
INSERT INTO #Temp(CountTotal, CountDate)
SELECT COUNT(DISTINCT PERSON.Id) AS CountTotal, @StartDT AS CountDate FROM PERSON
INNER JOIN DATA_INPUT_CHANGE_LOG ON PERSON.DataInputTypeId = DATA_INPUT_CHANGE_LOG.DataInputTypeId AND PERSON.Id = DATA_INPUT_CHANGE_LOG.DataItemId
LEFT OUTER JOIN PERSON_EMPLOYMENT ON PERSON.Id = PERSON_EMPLOYMENT.PersonId
WHERE PERSON.Id > 0 AND DATA_INPUT_CHANGE_LOG.Hidden = '0' AND DATA_INPUT_CHANGE_LOG.Approved = '1'
AND ((PERSON_EMPLOYMENT.StartDate <= DATEADD(MONTH,1,@StartDT) AND PERSON_EMPLOYMENT.EndDate IS NULL)
OR (@StartDT BETWEEN PERSON_EMPLOYMENT.StartDate AND PERSON_EMPLOYMENT.EndDate) AND PERSON_EMPLOYMENT.EndDate IS NOT NULL)
SET @StartDT = DATEADD(MONTH,1,@StartDT)
END
select * from #Temp
drop TABLE #Temp
答案 0 :(得分:0)
您可以通过创建数据来执行此操作,其中每个开始日期为+1事件,结束日期为-1,然后计算运行总计。
例如,如果您的数据是这样的
PersonId StartDate EndDate
1 20150101 20150201
2 20150102 20150115
3 20150101
首先创建一个如下所示的数据集:
EventDate ChangeValue
20150101 +2
20150102 +1
20150115 -1
20150201 -1
如果你使用总计,你会得到这个:
EventDate Total
2015-01-01 2
2015-01-02 3
2015-01-15 2
2015-02-01 1
你可以用这样的东西得到它:
select
p.eventdate,
sum(p.changevalue) over (order by p.eventdate asc) as total
from
(
select startdate as eventdate, sum(1) as changevalue from personnel group by startdate
union all
select enddate, sum(-1) from personnel where enddate is not null group by enddate
) p
order by p.eventdate asc
具有sum()的窗口函数需要SQL Server 2012.如果您使用的是旧版本,则可以检查其他选项以运行总计。
中的例子如果您的日期没有任何事件,并且您也需要显示这些事件,那么最佳选择可能是为您需要的整个范围创建一个单独的日期表,例如1.1.2000 - - 31.12.2099。
- 编辑 -
要获得特定日期的计数,可以使用相同的逻辑,但只需将所有内容汇总到那一天:
declare @eventdate date
set @eventdate = '20150117'
select
sum(p.changevalue)
from
(
select startdate as eventdate, 1 as changevalue from personnel
where startdate <= @eventdate
union all
select enddate, -1 from personnel
where enddate < @eventdate
) p
希望这没关系,因为SQL Fiddle似乎无法使用,所以无法测试。
答案 1 :(得分:0)
您可以使用以下查询。 cte部分是在开始日期和结束日期之间生成一组序列日期。
DECLARE @ViewStartDate DATETIME
DECLARE @ViewEndDate DATETIME
SET @ViewStartDate = '2015-01-01 00:00:00.000';
SET @ViewEndDate = '2015-02-25 00:00:00.000';
;WITH Dates([Date])
AS
(
SELECT @ViewStartDate
UNION ALL
SELECT DATEADD(DAY, 1,Date)
FROM Dates
WHERE DATEADD(DAY, 1,Date) <= @ViewEndDate
)
SELECT [Date], COUNT(*)
FROM Dates
LEFT JOIN PersonData ON Dates.Date >= PersonData.StartDate
AND Dates.Date <= PersonData.EndDate
GROUP By [Date]
将PersonData替换为您的表名
如果startdate和enddate列可以为null,则需要添加 加入的附加条件