1

この例では、作業しているテーブルが2つしかありません。どちらがより高速に実行され、実行プランが同じであるかを確認していました。これらのクエリの目的は、あるレコードに関連付けられている、別のレコードの最大日付よりも大きい最小日付を見つけることです。最初のクエリはより簡潔です(ただしDATEDIFF、2番目のクエリでは列が許可されません)。2番目の方法でクエリを作成すると、長期的には、おそらく多くの結合がある場合に、パフォーマンスの面でよりコストがかかるように感じます。どの方法についての一般的なルールはありますか、それともケースバイケースのシナリオであり、オプティマイザーにそれを実行させますか?

最初

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
    )

2番目

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
4

1 に答える 1

4

2つのクエリの実行プランが同じであることはすでに確認しました。これは驚くべきことではありません。SQLは記述言語であり、手続き型言語ではありません。つまり、言語は、それを生成する方法ではなく、生成されているものを記述します。

inステートメントまたはexistsサブクエリを含むステートメントを実行すると、結合が実行されます。構文は異なりますが、論理処理は同じです。これは、結合を表現するもう1つの方法です。エンジンが考慮に入れる必要があるいくつかの違いがあります。たとえば、「IN」はdistinctサブクエリで暗黙的に内部結合を実行しています。

好みの問題として、私は2番目のバージョンを好みます。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節でaを使用しています。これは単純な比較には不要です。「=」、「<」などを使用して日付を比較できます。

于 2012-10-25T16:05:25.487 に答える