我有我的表(cte)定义和结果集here
CTE可能看起来很奇怪,但已经过测试,并以我发现的最有效的方式返回正确的结果。以下查询将查找同时服用两种或更多种药物的人员ID(patid)。目前,该查询起作用,因为它返回同时服用两种药物但不同时服用两种药物的人的patID。一种fillDate
药物在另一种药物scriptEndDate
之前下降,表明服用这两种药物。所以
您可以在此部分结果集中看到第18行scriptFillDate
为2009-07-19
,它位于第2行相同patID的fillDate
和scriptEndDate
之间。我需要添加什么约束才能过滤掉这些不需要的结果?
--PatientDrugList is a CTE because eventually parameters might be passed to it
--to alter the selection population
;with PatientDrugList(patid, filldate, scriptEndDate,drugName,strength)
as
(
select rx.patid,rx.fillDate,rx.scriptEndDate,rx.drugName,rx.strength
from rx
),
--the row constructor here will eventually be parameters for a stored procedure
DrugList (drugName)
as
(
select x.drugName
from (values ('concerta'),('fentanyl'))
as x(drugName)
where x.drugName is not null
)
--the row number here is so that I can find the largest date range
--(the largest datediff means the person was on a given drug for a larger
--amount of time. obviously not a optimal solution
--celko inspired relational division!
select distinct row_number() over(partition by pd.patid, drugname order by datediff(day,pd.fillDate,pd.scriptEndDate)desc) as rn
,pd.patid
,pd.drugname
,pd.fillDate
,pd.scriptEndDate
from PatientDrugList as pd
where not exists
(select * from DrugList
where not exists
(select * from PatientDrugList as pd2
where(pd.patid=pd2.patid)
and (pd2.drugName = DrugList.drugName)))
and exists
(select *
from DrugList
where DrugList.drugName=pd.drugName
)
group by pd.patid, pd.drugName,pd.filldate,pd.scriptEndDate
答案 0 :(得分:1)
将原始查询包装到CTE中,或者更好的是,为了查询计划和结果的性能,稳定性,将其存储到临时表中。
以下查询(假设CTE选项)将为您提供两种药物的重叠时间。
;with tmp as (
.. your query producing the columns shown ..
)
select *
from tmp a
join tmp b on a.patid = b.patid and a.drugname <> b.drugname
where a.filldate < b.scriptenddate
and b.filldate < a.scriptenddate;