我有一个结构表
(RX)
clmID int
patid int
drugclass char(3)
drugName char(25)
fillDate date
scriptEndDate date
strength int
和查询
;with PatientDrugList(patid, filldate,scriptEndDate,drugClass,strength)
as
(
select rx.patid,rx.fillDate,rx.scriptEndDate,rx.drugClass,rx.strength
from rx
)
,
DrugList(drugName)
as
(
select x.drugClass
from (values('h3a'),('h6h'))
as x(drugClass)
where x.drugClass is not null
)
SELECT PD.patid, C.calendarDate AS overlap_date
FROM PatientDrugList AS PD, Calendar AS C
WHERE drugClass IN ('h3a','h6h')
AND calendardate BETWEEN filldate AND scriptenddate
GROUP BY PD.patid, C.CalendarDate
HAVING COUNT(DISTINCT drugClass) = 2
order by pd.patid,c.calendarDate
Calendar
是一个简单的日历表,其中包含整个研究期间的所有可能日期,没有其他列。
我的查询返回看起来像
的数据
overlap_date表示患者在PatientDrugList CTE之后列出的两个类别中被处方药物的每一天。
我想找到每个人开具两个药物系列的连续天数。我不能使用简单的max
和min
聚合,因为这不会告诉我是否有人停止了此方案然后重新开始。找到这个的有效方法是什么?
编辑:DrugList CTE中的行构造函数应该是存储过程的参数,并且为了本示例的目的进行了修改。
答案 0 :(得分:1)
您正在寻找连续的日期序列。关键的观察是,如果你从日期中减去一个序列,你将得到一个恒定的日期。这将按顺序定义一组日期,然后可以对其进行分组。
select patid
,MIN(overlap_date) as start_overlap
,MAX(overlap_date) as end_overlap
from(select cte.*,(dateadd(day,row_number() over(partition by patid order by overlap_Date),overlap_date)) as groupDate
from cte
)t
group by patid, groupDate
此代码未经测试,因此可能会有一些拼写错误。
答案 1 :(得分:-2)
你需要转向某种东西,并且最大限度地减少工作量。你能否说明某人是否在约会时有两种药物?如果我正确理解你的问题,那么你将按日期进行限制。
EG示例SQL:
declare @Temp table ( person varchar(8), dt date, drug varchar(8));
insert into @Temp values ('Brett','1-1-2013', 'h3a'),('Brett', '1-1-2013', 'h6h'),('Brett','1-2-2013', 'h3a'),('Brett', '1-2-2013', 'h6h'),('Joe', '1-1-2013', 'H3a'),('Joe', '1-2-2013', 'h6h');
with a as
(
select
person
, dt
, max(case when drug = 'h3a' then 1 else 0 end) as h3a
, max(case when drug = 'h6h' then 1 else 0 end) as h6h
from @Temp
group by person, dt
)
, b as
(
select *, case when h3a = 1 and h6h = 1 then 1 end as Logic
from a
)
select person, count(Logic) as DaysOnBothPresriptions
from b
group by person