Итак, у меня есть запрос, который выглядит примерно так

SELECT 
   CASE WHEN EXISTS(SELECT NULL 
                    FROM B 
                    WHERE B.LENGTH = A.LENGTH + 10) 
         THEN 'Yes'
         ELSE 'No'
   END AS Result1,
   CASE WHEN EXISTS(SELECT NULL
                    FROM B 
                    WHERE B.LENGTH = A.LENGTH - 10) 
         THEN 'Yes'
         ELSE 'No'
   END AS Result2,
   CASE WHEN EXISTS(SELECT NULL 
                    FROM B 
                    WHERE B.LENGTH = A.LENGTH) 
         THEN 'Yes'
         ELSE 'No'
   END AS Result3
FROM A

Как вы можете видеть, 3 запроса EXIST почти одинаковы, но с небольшой разницей, что (я надеюсь) могут быть переданы в качестве аргумента.

Я пытался создать TVF, но он не удается, когда я возвращаю SELECT NULL..., но работает, если я использую SELECT *. Чего я боюсь, так это того, что мне не нужны значения, которые я хочу проверить, если они существуют, и все.

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

0
chnging 16 Апр 2019 в 14:01

2 ответа

Лучший ответ

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

SELECT CASE WHEN CA.C1 > 0 THEN 'Yes' ELSE 'No' END
     , CASE WHEN CA.C2 > 0 THEN 'Yes' ELSE 'No' END
     , CASE WHEN CA.C3 > 0 THEN 'Yes' ELSE 'No' END
FROM A
CROSS APPLY (
    SELECT COUNT(CASE WHEN B.LENGTH = A.LENGTH + 10 THEN 1 END)
         , COUNT(CASE WHEN B.LENGTH = A.LENGTH - 10 THEN 1 END)
         , COUNT(CASE WHEN B.LENGTH = A.LENGTH      THEN 1 END)
    FROM B
    WHERE B.LENGTH IN (A.LENGTH + 10, A.LENGTH - 10, A.LENGTH)
) AS CA(C1, C2, C3)
2
Salman A 16 Апр 2019 в 12:26

Вы можете сделать что-то вроде этого:

SELECT A.Length,
       CASE COUNT(CASE A.[LENGTH] WHEN B.[LENGTH] - 10 THEN 1 END)WHEN 0 THEN 'No' ELSE 'Yes' END AS result1,
       CASE COUNT(CASE A.[LENGTH] WHEN B.[LENGTH] + 10 THEN 1 END)WHEN 0 THEN 'No' ELSE 'Yes' END AS result2,
       CASE COUNT(CASE A.[LENGTH] WHEN B.[LENGTH] THEN 1 END)WHEN 0 THEN 'No' ELSE 'Yes' END AS result3
FROM A
     CROSS JOIN B
GROUP BY A.Length;

Это экономит 3 сканирования таблицы B, но вам все равно потребуется какая-то повторяющаяся логика.

0
Larnu 16 Апр 2019 в 11:21