web-dev-qa-db-ja.com

条件付き内部結合

式の結果に基づいて2つのテーブルを内部結合できるようにしたい。

私がこれまで試みてきたこと:

INNER JOIN CASE WHEN RegT.Type = 1 THEN TimeRegistration ELSE DrivingRegistration AS RReg
ON
RReg.RegistreringsId = R.Id

RegTは、この結合の直前に行った結合です。

INNER JOIN RegistrationTypes AS RegT ON R.RegistrationTypeId = RegT.Id

このSQLスクリプトは機能しません。

つまり、全体として、Typeが1の場合、テーブルTimeRegistrationで結合する必要があります。それ以外の場合は、DrivingRegistrationで結合する必要があります。

ソリューション:

私の選択ステートメントでは、次の結合を実行しました。

INNER JOIN  RegistrationTypes AS RegT ON R.RegistrationTypeId = RegT.Id
LEFT OUTER JOIN TimeRegistration AS TReg ON TReg.RegistreringsId = R.Id AND RegT.Type = 1
LEFT OUTER JOIN DrivingRegistration AS DReg ON DReg.RegistreringsId = R.Id AND RegT.Type <>1

次に、where-clauseは、次のようにRegTypeに応じて正しい出力を行います。

WHERE (CASE RegT.Type WHEN 1 THEN TReg.RegistreringsId ELSE DReg.RegistreringsId END = R.Id)
23
KristianB

LEFT JOINを使用して両方のテーブルをクエリに入れてみてください

LEFT JOIN TimeRegistration TR ON r.rid = TR.Id AND RegT.type =1 
LEFT JOIN DrivingRegistration DR ON r.rid = DR.Id AND RegT.type <>1 

今、あなたはselect句で、

CASE RegType.Type WHEN 1 THEN TR.SomeField ELSE DR.someField END as SomeField

もう1つのオプションは、動的SQLを使用することです

20
Sparky

おそらく2つの左結合を実行して、1つをTimeRegistrationに、もう1つをDrivingRegistrationに実行し、適切な結合テーブルから必要なフィールドを次のように返す必要があります。

LEFT JOIN TimeRegistration ON TimeRegistration.RegistreringsId = R.Id
LEFT JOIN DrivingRegistration ON DrivingRegistration.RegistreringsId = R.Id

そして、selectステートメントは次のようになります。

SELECT CASE WHEN RegT.Type = 1 THEN TimeRegistration.Foo ELSE DrivingRegistration.Bar END

私はあなたがやろうとしていることが好きですが、SQLはそれほど賢いとは思いません。

9
David
SELECT
  R.foo, tr.bar
FROM
  SomeTable AS R
  INNER JOIN RegistrationTypes AS RegT ON R.RegistrationTypeId = RegT.Id 
                                          AND RegT1.Type = 1
  INNER JOIN TimeRegistration AS tr    ON /* whatever */

UNION 

SELECT
  R.foo, dr.bar
FROM
  SomeTable AS R
  INNER JOIN RegistrationTypes AS RegT ON R.RegistrationTypeId = RegT.Id 
                                          AND RegT1.Type = 2
  INNER JOIN DrivingRegistration AS dr ON /* whatever */
1
Tomalak

そのため、1つのテーブルに3つの電子メール列があり(理由は尋ねないでください)、null(または空)になる可能性のあるシナリオがありました。このサンプルコードでは、nullの場合のみを扱います。

ユーザーの名を取得するために、電子メールで別のテーブルに結合する必要がありました。

これがうまくいきました

select  

m.email1,
m.email2,
m.email3, 
m2.firstName

from MyTable m

left join MyOtherTable m2 on m2.Email = 
case when m.email1 is null then 

    case when m.email2 is null then 

        case when m.email3 null then 
            '[email protected]' -- i stopped here
        else m.email3 end

    else wm.email2 end

else m.email1 end

明らかに、あなたは次のような条件を追加します

case when m.email1 is null or m.email1 = '' then ...

空の値をカバーするため。

0
ozzy432836