给出如下数据集:
ID admission_date discharge_date
1 2016-02-27 2016-05-06
2 2016-03-06 2016-05-13
3 2016-03-14 2016-05-03
4 2016-04-01 2016-05-19
5 2016-04-03 2016-06-15
6 2016-04-06 2016-05-14
7 2016-04-27 2016-05-03
8 2016-04-27 2016-05-10
9 2016-04-28 2016-05-04
10 2016-04-28 2016-05-01
11 2016-04-28 2016-05-14
12 2016-04-29 2016-05-02
13 2016-04-29 2016-05-01
我想计算给定范围内每行中发生的行数(即进行每日普查)。对于从“ 2016-05-01”到“ 2016-05-02”的每日人口普查,预期结果是:
date census
2016-05-01 13
2016-05-02 11 (rows 10 and 13 do not count because patient
was not hospitalized on 2016-05-02)
我正在努力寻找一种方法来正确汇总所有天的人口普查计数。我走了一段时间的窗口函数之路,但我想不出一种排除行以达到上述结果的方法。目前,我正在尝试通过使用游标来解决此问题。
所以问题是:是否可以使用纯声明性SQL查询来做到这一点?
为了显示关于人们认为“普查”的观点,this thread in Tableau forums讨论了几乎相同的想法,但是主要区别在于,这里讨论的方法假设对于2016-05-01,您不会例如,对2016年5月1日出院的患者进行计数(此想法使您每天可以使用窗口功能进行总结)。这将使2016-05-01以上的总数减少到11。
答案 0 :(得分:1)
如果您有日期表,这是可能的。如果没有,则可以使用递归cte生成它们并将其用于查询。
--Use the recursive cte only if there isn't a dates table in the database
--Generates all dates in 2016
with dates(dt) as (select cast('2016-01-01' as date)
union all
select dateadd(day,1,dt)
from dates
where dt<'2017-01-01'
)
--Actual query
select d.dt,count(distinct t.id)
from tbl t
join dates d on d.dt>=t.admission_date and d.dt<=t.dishcarge_date
where d.dt>='2016-05-01' and d.dt<='2016-05-02' --change this as needed
group by d.dt
option (maxrecursion 0)
答案 1 :(得分:1)
这是一种仅在您列出的日期提供普查的方法:
with d as (
select v.*
from t cross apply
(values (admission_date, 1, 0),
(discharge_date, 0, 1)
) v(dte, incoming, outgoing)
)
select dte,
(sum(sum(incoming)) over (order by dte) - sum(sum(outgoing)) over (order by dte)
) as census
from d
group by dte
order by dte;
这可能是最快的方法。如果您有日历表或想使用递归CTE,则可以将其扩展到所有日期。