在这个例子中,我只有两张桌子,我正在工作。我正在检查哪些可能运行得更快,执行计划是相同的。这些查询的目的是找到与一个记录相关联的最小日期,该记录大于另一个记录的最大日期。第一个查询更简洁(尽管它不允许第二个查询的DATEDIFF
列)。从长远来看,我觉得编写查询是第二种方式,性能更高,也许当我有很多连接时。是否有关于哪种方法的一般规则,或者是否是一个案例场景,你让优化器解决了吗?
第一
select c.patid,min(c.admitDate) as minDiabetesDate
from clm_extract as c
inner join icdClm as ic on ic.clmid=c.clmid
where ic.icd like '250%'
group by c.patid
having min(c.admitdate) >
(
select MAX(c2.admitDate) as maxPreDiabetesDate
from clm_extract as c2
inner join icdClm as ic2 on ic2.clmid = c2.clmid
where ic2.icd ='79029' and c2.patid=c.patid
group by c2.patid
)
第二
select distinct x.patid,x.minDiabetesDate,y.maxPreDiabetesDate
from
(
select c.patid, min(c.admitdate) as minDiabetesDate
from clm_extract as c
inner join icdClm as ic on ic.clmid=c.clmid
where ic.icd like '250%'
group by c.patid
)x
inner join
(
select c2.patid, MAX(c2.admitdate) as maxPreDiabetesDate
from clm_extract as c2
inner join icdClm as ic2 on ic2.clmid=c2.clmid
where ic2.icd ='79029'
group by c2.patid
)y on x.patid=y.patid
group by x.minDiabetesDate,y.maxPreDiabetesDate,x.patid
having DATEDIFF(dd,y.MaxPreDiabetesDate,x.minDiabetesDate) > 0
答案 0 :(得分:4)
您已经观察到这两个查询具有相同的执行计划。这并不奇怪。 SQL是描述性语言,而不是过程语言。也就是说,语言描述了正在生成的内容,而不是生成它的方法。
当您使用子查询执行in
语句或exists
语句时, 正在执行连接。语法不同,但逻辑处理是相同的。这只是表达联接的另一种方式。引擎需要考虑一些差异。例如,一个“IN”正在子查询中使用隐式distinct
进行内连接。
作为优先选择,我更喜欢第二个版本。我希望尽可能在from
子句中提到的查询中使用表。
在考虑了您的查询之后,有一种更简单的方法来编写它:
select c.patid,
min(case when ic.icd like '250%' then c.admitDate end) as minDiabetesDate,
MAX(case when ic.icd = '79029' then c.admitDate end) as maxPreDiabetesDate
from clm_extract c
inner join
icdClm ic
on ic.clmid=c.clmid
where ic.icd like '250%' or ic.icd = '79029'
group by c.patid
having MAX(case when ic.icd = '79029' then c.admitDate end) <
min(case when ic.icd like '250%' then c.admitDate end)
这将case
语句与聚合函数结合使用来计算所需的日期。顺便说一句,您在datediff
子句中使用了having
。对于简单的比较,这是不必要的。您可以使用“=”,“&lt;”等来比较日期。