Условное внутреннее соединение - PullRequest
22 голосов
/ 01 сентября 2011

Я хочу иметь возможность внутреннего объединения двух таблиц на основе результата выражения.

То, что я пытался до сих пор:

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.

Решение:

В своем утверждении select я выполнил следующие объединения:

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)

Ответы [ 4 ]

19 голосов
/ 01 сентября 2011

Попробуйте поместить обе таблицы в запрос, используя 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 

Теперь, когда вы выбираете предложение, используйте

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

Другой вариант - использовать динамический SQL

8 голосов
/ 01 сентября 2011

Вам, вероятно, нужно выполнить два левых соединения, одно на TimeRegistration, а другое на DrivingRegistration и вернуть нужные поля из соответствующей таблицы соединений примерно так:

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

и вы выбираете оператор будет примерно так:

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

Мне нравится то, что вы пытаетесь сделать, но я не думаю, что SQL такой умный.

1 голос
/ 01 сентября 2011
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 */
0 голосов
/ 10 октября 2018

Итак, у меня был сценарий, когда в одной таблице было три столбца электронной почты (не спрашивайте почему), и любой из них мог быть нулевым (или пустым). В этом примере кода я буду иметь дело со случаем, когда он равен нулю.

Мне пришлось присоединить его к другой таблице по любому из электронных писем, чтобы получить имя пользователя.

Вот что сработало

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 
            'nonexistent@mydomain.com' -- 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 ...

Для покрытия пустых значений.

...