SQL Server Условный запрос CASE JOIN - PullRequest
0 голосов
/ 29 ноября 2018

Может ли кто-нибудь помочь мне при условном присоединении?Я хочу присоединиться к ID и [Имя] из обеих таблиц, и следующее условие будет похоже на

СЛУЧАЙ КОГДА a.Count = b.Count THEN a.Rn1 = b.Rn1 WHEN a.Count <>b.Count THEN a.Rn2 = b.Rn2 и a.Rn3 = b.Rn3 END

DROP TABLE IF EXISTS #Test1
DROP TABLE IF EXISTS #Test2

CREATE TABLE #Test1 (ID int, [name] varchar(50),[Count] int, Rn1 int, Rn2 int, Rn3 int)
CREATE TABLE #Test2 (ID int, [name] varchar(50),[Count] int, Rn1 int, Rn2 int, Rn3 int)

Insert Into #Test1 
Values 
 (123123,'Hours',6,1,1,1)
,(123123,'Hours',6,2,1,2)
,(123123,'Hours',6,3,2,1)
,(123123,'Hours',6,4,3,1)
,(123123,'Hours',6,5,3,2)
,(123123,'Hours',6,6,4,1)
,(123123,'NI1',1,1,1,1)
,(123123,'NI2',1,1,1,1)
,(123123,'PAY',1,1,1,1)
,(123123,'Teachers1',1,1,1,1)
,(123123,'Teachers2',1,1,1,1)

,(123124,N'Hours',5,1,1,1)
,(123124,N'Hours',5,2,2,1)
,(123124,N'Hours',5,3,3,1)
,(123124,N'Hours',5,4,3,2)
,(123124,N'Hours',5,5,4,1)
,(123124,N'NI1',1,1,1,1)
,(123124,N'NI2',1,1,1,1)
,(123124,N'PAY',1,1,1,1)

--SELECT * FROM #Test1 

Insert Into #Test2
Values (123123,N'Hours',6,1,1,1)
,(123123,N'Hours',6,2,1,2)
,(123123,N'Hours',6,3,2,1)
,(123123,N'Hours',6,4,3,1)
,(123123,N'Hours',6,5,3,2)
,(123123,N'Hours',6,6,4,1)
,(123123,N'NI1',1,1,1,1)
,(123123,N'NI2',1,1,1,1)
,(123123,N'PAY',1,1,1,1)
,(123123,N'Teachers1',1,1,1,1)
,(123123,N'Teachers2',1,1,1,1)

,(123124,N'Hours',6,1,1,1)
,(123124,N'Hours',6,2,2,1)
,(123124,N'Hours',6,3,3,1)
,(123124,N'Hours',6,4,3,2)
,(123124,N'Hours',6,5,3,3)
,(123124,N'Hours',6,6,4,1)
,(123124,N'NI1',1,1,1,1)
,(123124,N'NI2',1,1,1,1)
,(123124,N'PAY',1,1,1,1)

--SELECT * FROM #Test2

Спасибо за вашу помощь заранее.

Ответы [ 3 ]

0 голосов
/ 29 ноября 2018

Вы пытаетесь использовать выражение CASE как выражение CASE.CASE выражение возвращает скалярное значение, а не логический результат.Так, например, допустим следующий синтаксис:

WHERE CASE [Column] WHEN 'A' THEN 1 ELSE 2 END = OtherColumn;

Это потому, что выражение CASE возвращает скалярное значение 1 или 2.Следующее утверждение будет недопустимым:

WHERE CASE [Column] WHEN 'A' THEN OtherColumn = 1 ELSE OtherColumn = 2 END;

A CASE в WHERE в T-SQL должно быть частью логического выражения ({CASE expression} {=|!=|>|<|etc} {Expression}), а не возвращать его.

Использование выражения CASE в предложении WHERE, однако, делает ваш запрос не SARGable, вам гораздо лучше исправить некоторую логическую логику.То, что у вас есть, вероятно, будет:

WHERE (A.[Count] = b.[Count]
  AND  A.RN1 = B.RN1)
   OR (A.[Count] != b.[Count]
  AND  A.RN2 = B.RN2
  AND  A.RN3 = B.RN3);
0 голосов
/ 30 ноября 2018

Можно сделать что-то подобное с выражениями CASE:

WHERE 1 = (CASE WHEN a.Count = b.Count THEN  CASE WHEN a.Rn1 = b.Rn1 THEN 1 END 
                WHEN a.Count <> b.Count THEN CASE WHEN a.Rn2 = b.Rn2 and a.Rn3 = b.Rn3 THEN 1 END
           END) 

Это буквальный перевод исходного запроса без какой-либо оптимизации.

0 голосов
/ 29 ноября 2018

Предикаты выражения CASE (т. Е. Того, что следует за THEN и ELSE) всегда должны быть значением, а не другим логическим выражением.Не видя весь ваш запрос, я могу предложить следующий рефакторинг:

WHERE
    (a.Count = b.Count AND a.Rn1 = b.Rn1) OR
    (a.Count <> b.Count AND a.Rn2 = b.Rn2 AND a.Rn3 = b.Rn3)
...