使用声明性查询进行每日普查

时间:2018-10-06 00:49:02

标签: sql sql-server

给出如下数据集:

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。

2 个答案:

答案 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,则可以将其扩展到所有日期。

相关问题