SQL: повторное использование запроса с EXIST - PullRequest
0 голосов
/ 16 апреля 2019

Хорошо, у меня есть запрос, похожий на

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 *. Чего я боюсь, так это того, что мне не нужны значения, которые я хочу проверить, если они существуют, и все.

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

Ответы [ 2 ]

2 голосов
/ 16 апреля 2019

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

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)
0 голосов
/ 16 апреля 2019

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

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, но вам все равно понадобится повторяющаяся логика некоторого вида.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...