Мыслительный процесс синтаксиса CASE в SQL

У меня есть следующий код (я использую базу данных Northwind), который дает мне результат, показанный на этом рисунке

SELECT a.FirstName, a.TitleOfCourtesy, a.Notes, c.CustomerYear
FROM employees a
    INNER JOIN orders b
    ON a.EmployeeID = b.EmployeeID
    LEFT JOIN customers c
    ON b.CustomerID = c.CustomerID
WHERE a.TitleOfCourtesy = 'Ms.';

Приведенный выше код объединяет три таблицы и выбирает только строки с a.TitleOfCourtesy = 'Ms.'

Из результата я хочу взять строки, в которых %1992% находится в столбце a.Notes, и показать только строки, в которых c.CustomerYear равно 1992. Таким образом, на рисунке выше я должен увидеть только вторую верхнюю строку.

Я думал, что смогу использовать синтаксис CASE + WHEN для создания своего рода оператора IF, но я получаю недопустимое использование синтаксиса только в строке CASE. Должна ли часть CASE быть перемещена после части WHERE или я использую ее совершенно неправильно?

SELECT a.FirstName, a.TitleOfCourtesy, a.Notes, c.CustomerYear

CASE 
    WHEN a.Notes LIKE '%1992%' THEN c.CustomerYear LIKE '1992' 
    ELSE NULL END 

FROM employees a
    INNER JOIN orders b
    ON a.EmployeeID = b.EmployeeID
    LEFT JOIN customers c
    ON b.CustomerID = c.CustomerID
WHERE a.TitleOfCourtesy = 'Ms.';

Как я должен думать, чтобы достичь желаемого результата?


person Linda Stenn    schedule 21.09.2018    source источник
comment
CASE предназначен для изменения значения в зависимости от строки, но не фильтрует строки. WHERE предназначен для фильтрации строк.   -  person Bohemian♦    schedule 22.09.2018
comment
Пока я пытаюсь понять, не могли бы вы привести краткий пример того, что вы имеете в виду: изменение значения в зависимости . Это будет высоко ценится!!   -  person Linda Stenn    schedule 22.09.2018


Ответы (1)


Вам просто нужно расширить предложение WHERE...

SELECT a.FirstName, a.TitleOfCourtesy, a.Notes, c.CustomerYear
FROM employees a
    INNER JOIN orders b
    ON a.EmployeeID = b.EmployeeID
    LEFT JOIN customers c
    ON b.CustomerID = c.CustomerID
WHERE a.TitleOfCourtesy = 'Ms.'
  AND a.Notes LIKE '%1992%'
  AND c.CustomerYear LIKE '1992';

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

SELECT a.FirstName, a.TitleOfCourtesy, a.Notes, c.CustomerYear
FROM employees a
    INNER JOIN orders b
    ON a.EmployeeID = b.EmployeeID
    LEFT JOIN customers c
    ON b.CustomerID = c.CustomerID
WHERE a.TitleOfCourtesy = 'Ms.'
  AND a.Notes LIKE '%1992%'
  AND (c.CustomerYear LIKE '1992' OR c.CustomerYear IS NULL)

Наконец, вам не нужно LIKE '1992', вы можете просто использовать = '1992', а если значение является целым числом, просто используйте = 1992...

person MatBailie    schedule 21.09.2018
comment
Да, это сработало, теперь мне нужно только понять, почему мне не нужно было использовать синтаксис CASE, поскольку я думал, что он используется для создания условий... Или это только проблема с фильтром, которая у меня была, а не проблема с оценкой? - person Linda Stenn; 22.09.2018
comment
Я был недостаточно ясен. Ваш первый код был тем, что я искал. Должна быть видна только одна строка (2-я строка сверху), поскольку она содержит значение 1992 как в столбце a.Notes, так и в столбце c.CustomerYear. - person Linda Stenn; 22.09.2018
comment
@LindaStenn CASE фактически SWITCH. Он принимает скалярные значения и возвращает один скалярный результат. Как встроенный IF? CASE number % 2 WHEN 0 THEN 'even' WHEN 1 THEN 'odd' ELSE 'NULL' END принимает число и возвращает одну из трех возможных строк... - person MatBailie; 22.09.2018
comment
@mat ELSE NULL является избыточным, это подразумевается, если нет совпадений - person Bohemian♦; 22.09.2018
comment
@Bohemian За исключением того, что я не писал ELSE NULL, я написал ELSE 'NULL', чтобы вернуть строку, а не значение NULL. - person MatBailie; 22.09.2018