Выражение SQL CASE, объяснение для начинающих
Выучить весь язык, а не только этот фрагмент? SQL для аналитиков, полная версия объединяет 239-страничное руководство, систему комментариев и руководство по аналитическому мышлению в один пакет. SQL для аналитиков, полная версия, 39 долларов США →
CASE — это оператор SQL если/иначе. Именно так вы очищаете беспорядочные значения, сортируете числа по группам, строите флаги и подсчитываете несколько вещей в одном запросе.
Это руководство охватывает все это. Как решает CASE. Обе формы синтаксиса. Два правила, которые нарушают CASE вообще без сообщения об ошибке: одно о порядке, а другое о NULL. Везде в запросе разрешено использовать CASE. И как строятся настоящие правила уборки, на реальных данных, включая ошибки.
- Что такое CASE и как он решает
- Главное правило: порядок — это логика
- Реальный пример: очистка кредитов артистов Рекламный щит
- Вторая форма: CASE со столбцом вверху.
- NULL-ловушка, которая вообще не выдает ошибок.
- Куда разрешено рассмотрение ДЕЛА
- Четыре аналитика вакансий используют CASE для
- Как создать действительно правильное правило CASE
- Шпаргалка
Что такое CASE и как он решает
CASE производит одно значение в строке проверив список тестов сверху вниз:
CASE
WHEN <test 1> THEN <value 1>
WHEN <test 2> THEN <value 2>
ELSE <fallback value>
END
тот первый пройденный тест побеждает. Его значение THEN становится результатом, и каждый тест ниже него пропускается. Если ничего не проходит, вы получаете значение ELSE. Если нет ELSE, вы получаете NULL.
У этой сложенной фигуры есть имя. Официально это искал выражение CASE. Аналитики обычно называют это КЕЙС лестница, поскольку каждая пара КОГДА/ТОгда представляет собой ступеньку. Если вы знаете другой язык, это цепочка если/иначе-если/иначе.
CREATE TABLE … AS, чтобы сохранить значение в таблице. Или внутри SUM и COUNT, которые представляют собой условное агрегирование ниже.Главное правило: порядок — это логика
Прежде чем читать, продумайте последствия. Если первая совпавшая ступень выигрывает, и обе ступени могут соответствовать одной и той же строке, каков при этом будет порядок ступеней? Ответьте на этот вопрос, и у вас есть правило.
Выигрывает первая совпавшая ступень, поэтому порядок ступеней меняет ответ. Две ступени могут быть правильными сами по себе, но вместе давать неправильный результат. Это происходит, когда общая ступень находится над конкретной. Это дает вам правило:
Конкретные шаблоны превосходят содержащиеся в них общие шаблоны.
Это абстрактно, пока вы не увидите, что на реальных данных все идет не так:
Реальный пример: очистка кредитов артистов Рекламный щит
В истории публичных чартов Рекламный щит Горячий 100 (бесплатный CSV, начиная с 1958 года) имена исполнителей указаны следующим образом:
2 Chainz Featuring Drake
Elvis Presley With The Jordanaires
2Pac Duet With Mopreme
Patti Austin A Duet With James Ingram
Для анализа по исполнителям вам понадобится начальный художник — текст перед соединительным словом. Соединительным словом является то, что связывает два имени: «С участием», «С», «Дуэт с». Лестница CASE подойдет именно вам. Первая попытка знала двух столяров:
CASE
WHEN INSTR(performer, ' Featuring ') > 0
THEN SUBSTR(performer, 1, INSTR(performer, ' Featuring ') - 1)
WHEN INSTR(performer, ' With ') > 0
THEN SUBSTR(performer, 1, INSTR(performer, ' With ') - 1)
ELSE performer
END
INSTR находит место появления фрагмента текста. SUBSTR вырезает все, что было до этого.
Предварительный просмотр правила на реальных строках сразу выявил дефект. «2Пак Дуэт с Мопремом» вышел как «2Пак Дуэт».. Тот кредит соединяется с "Дуэтом С", но лестница знала только "С". Значит, срезали не там, где надо, и придумали художника, которого нет.
Исправление заключается в добавлении ' Duet With ' Рунг выше ' With '. Затем еще раз проверьте те строки, которые должно было быть обнаружено исправлением. Выяснилось еще одно: «Патти Остин: Дуэт с Джеймсом Ингрэмом» вышла как «Патти Остин А».. В титрах написано «Дуэт с», а не «Дуэт с». Значит, нужна еще одна ступенька, еще один уровень более конкретный, расположенный на одну ступеньку выше. Готовая лестница:
CASE
WHEN INSTR(performer, ' A Duet With ') > 0
THEN SUBSTR(performer, 1, INSTR(performer, ' A Duet With ') - 1)
WHEN INSTR(performer, ' Duet With ') > 0
THEN SUBSTR(performer, 1, INSTR(performer, ' Duet With ') - 1)
WHEN INSTR(performer, ' Featuring ') > 0
THEN SUBSTR(performer, 1, INSTR(performer, ' Featuring ') - 1)
WHEN INSTR(performer, ' With ') > 0
THEN SUBSTR(performer, 1, INSTR(performer, ' With ') - 1)
ELSE performer
END AS primary_artist
Прочтите сверху вниз. Каждая ступень является более общей, чем предыдущая, поэтому конкретные случаи выявляются до того, как общая ступень сможет их исказить. В полном наборе данных эта лестница объединила 11 275 строк необработанных кредитов в 8 896 чистых основных исполнителей.
Вторая форма: CASE со столбцом вверху.
Все вышеперечисленное использует составную форму, где каждый WHEN выполняет свой собственный полный тест. Существует вторая, более короткая форма для общего случая, когда каждый тест сравнивает такой же столбец против другого значения. Поднимите колонку и поместите ее сразу после CASE:
CASE status
WHEN 'active' THEN 'yes'
WHEN 'churned' THEN 'no'
ELSE 'unknown'
END
Это то же самое, что написать WHEN status = 'active' в каждой строке, с меньшим повторением. Официально это простое выражение CASE. Сложенный вариант, использованный ранее, представляет собой искал выражение CASE. Эти два имени постоянно встречаются в документации, и это единственная разница между ними.
Краткая форма означает только равенство. Момент, который вам нужен >, <, LIKE, IS NULLили два разных столбца в одном тесте, вам придется вернуться к составной форме. Вот почему большинство аналитических SQL для всего использует сложную форму: она охватывает обе задачи, и вам никогда не придется преобразовывать CASE на полпути его написания.
NULL-ловушка, которая вообще не выдает ошибок.
Перед ответом: в столбце есть пустые значения. Ты пишешь WHEN score = NULL THEN 'missing'. Как вы думаете, сколько строк вернётся с пометкой «отсутствует»?
Никто. Ни одного, никогда, ни в одной базе данных. И ничто вас не предупреждает.
NULL в SQL не означает пустое. Это означает неизвестный. Так score = NULL не спрашивает «это пусто», он спрашивает «равно ли это неизвестное значение этому другому неизвестному значению», и честный ответ на этот вопрос — ни да, ни нет. Тест никогда не возвращается истинным, ступенька никогда не срабатывает, и каждая строка попадает в ваш ELSE. В таблице, где треть строк пусты, результат выглядит вполне разумным и совершенно неправильным для всех из них.
-- Never marks anything. Every row falls to the ELSE.
CASE WHEN score = NULL THEN 'missing' ELSE 'has a score' END
-- Correct. IS NULL is the test that works on unknowns.
CASE WHEN score IS NULL THEN 'missing' ELSE 'has a score' END
То же самое относится и к краткой форме. CASE score WHEN NULL THEN … в основе лежит равенство, поэтому оно терпит неудачу точно таким же молчаливым образом. NULL-проверка всегда должна быть записана как отдельная. WHEN … IS NULL ступенька в сложенной форме.
Есть второе, меньшее по размеру поведение NULL, о котором стоит знать, и оно полезно. Если ни одна цепочка не соответствует и вы не написали ELSE, результат будет NULL. Вот почему условный подсчет вообще работает без ELSE: COUNT(CASE WHEN status = 'active' THEN 1 END) подсчитывает совпадения, поскольку COUNT пропускает NULL, а все несовпадения становятся NULL.
WHEN <column> IS NULL верхняя ступенька лестницы. Это самый специфический случай, поэтому согласно приведенному выше правилу упорядочивания он находится наверху, и размещение его там означает, что вам никогда не придется потом задаваться вопросом, в какое ведро попали заготовки.Куда разрешено рассмотрение ДЕЛА
CASE создает значение, поэтому оно может находиться везде, где может находиться столбец. Это больше мест, чем использует большинство людей, и каждое из них решает свою проблему.
| Место | Что он там делает | Пример |
|---|---|---|
SELECT | Создает новый столбец | CASE WHEN score > 50 THEN 'high' ELSE 'low' END AS band |
WHERE | Фильтры по вычисленному значению | WHERE CASE WHEN score IS NULL THEN 0 ELSE score END > 50 |
ORDER BY | Сортировка в порядке, отличном от алфавитного или числового. | ORDER BY CASE status WHEN 'urgent' THEN 1 WHEN 'normal' THEN 2 ELSE 3 END |
GROUP BY | Группируется по придуманной вами полосе, а не по сохраненному столбцу. | GROUP BY CASE WHEN score >= 50 THEN 'high' ELSE 'low' END |
внутри SUM или COUNT | Считает несколько разных вещей за один проход | См. условную агрегацию ниже. |
UPDATE … SET | Записывает разные значения для каждой строки в одном операторе | SET band = CASE WHEN score > 50 THEN 'high' ELSE 'low' END |
Людям не хватает пользовательской сортировки в ORDER BY. Каждый раз, когда вы хотите, чтобы статусы отображались в бизнес-порядке, а не в алфавитном порядке, это СЛУЧАЙ, и другого чистого способа сделать это не существует.
WHERE band = 'high', зависит от базы данных. Кто-то это допускает, кто-то отвергает. Вариант, который работает везде, — это повторение всего выражения или вычисление его один раз за цикл. CTE и отфильтровать CTE. CTE — это читаемый вариант, и именно на нем останавливается большинство аналитиков.Четыре аналитика вакансий используют CASE для
1. Очистка и нормализация
Сопоставление беспорядочных исходных значений с чистыми, как это показано на лестнице Рекламный щит выше. Любой набор данных, в котором одна реальная вещь встречается под несколькими вариантами написания, нуждается в такой лестнице.
2. Ведро
Превращение непрерывного числа в именованные полосы:
CASE
WHEN age < 18 THEN 'minor'
WHEN age < 65 THEN 'adult'
ELSE 'senior'
END AS age_band
Уровни доходов, диапазоны вовлеченности и рейтинговые группы — все это форма. Обратите внимание, что порядок и здесь имеет значение. age < 65 также подойдет 10-летнему ребенку. Чем более конкретно age < 18 сидит над ним, поэтому ловит их первым.
3. Флаги
Столбец «да/нет», полученный в результате теста, например CASE WHEN peak_position <= 10 THEN 1 ELSE 0 END AS top10_hit. Флаг упрощает последующую фильтрацию, объединение и подсчет.
4. Условное агрегирование (трюк с поворотом)
CASE внутри SUM или COUNT подсчитывает разные значения за один проход по таблице:
SELECT
SUM(CASE WHEN genre = 'Country' THEN 1 ELSE 0 END) AS country_songs,
SUM(CASE WHEN genre = 'Pop' THEN 1 ELSE 0 END) AS pop_songs
FROM songs;
Один запрос, несколько счетчиков рядом. Это рабочая лошадка сводных таблиц и плиток информационной панели.
Как создать действительно правильное правило CASE
Теперь возьмите беспорядочную колонку из своей работы и изобразите для нее лестницу. Какова первая ступенька и что опускается до нижней? Строки, которые не выпадают, — это именно те строки, для которых на самом деле предназначен этот метод.
| Шаг | Что вы делаете |
|---|---|
| 1. Черновик | Напишите лестницу, в которую вы верите. |
| 2. Предварительный просмотр | Запустите его на реальных строках ПЕРЕД созданием чего-либо из него: исходного значения и вычисленного значения рядом, и прочитайте их. |
| 3. Исправить | При появлении неправильных результатов добавьте недостающую цепочку над общей цепочкой, которая обработала его неправильно. |
| 4. Подтвердите | Перепроверьте точные строки, на которые нацелено исправление, а не просто случайную выборку. |
| 5. Итерация | Повторяйте до тех пор, пока исключения не перестанут появляться. Именно так правила нормализации строятся на практике. |
Шпаргалка
| Вы хотите | Писать | Следите за |
|---|---|---|
| Тестируйте разные вещи на каждой ступеньке | CASE WHEN a > 1 THEN … WHEN b = 'x' THEN … END | Первый матч выигрывает, поэтому порядок — это логика |
| Сравнить один столбец с несколькими значениями | CASE status WHEN 'a' THEN … WHEN 'b' THEN … END | Только равенство, нет > или LIKE |
| Ловить пустые значения | WHEN col IS NULL THEN … | = NULL никогда не совпадает и никогда не ошибается |
| Придайте всему остальному одно значение | ELSE 'other' | Больше нет означает, что несовпадающие строки имеют значение NULL. |
| Сортировать по бизнес-заказу | ORDER BY CASE status WHEN 'urgent' THEN 1 … END | Числа — это просто ключи сортировки, а не вывод |
| Посчитайте две вещи в одном запросе | SUM(CASE WHEN … THEN 1 ELSE 0 END) | Использовать COUNT(CASE WHEN … THEN 1 END) чтобы пропустить ELSE |
| Повторное использование вычисляемого столбца позже | Вычислите это в CTE, затем отфильтруйте CTE | Повторное использование псевдонима в WHERE непереносимо. |
| Ставьте конкретное выше общего | ' A Duet With ' выше ' Duet With ' выше ' With ' | Общая ступенька сверху поглощает конкретные |
Единственная привычка, которую нужно сохранить
Никогда не отправляйте CASE, который вы не просмотрели рядом с исходной колонкой. Каждый дефект в этом руководстве, включая несуществующего художника, был обнаружен путем размещения входных и выходных данных рядом друг с другом и чтения двадцати строк. Ничто другое не удерживает лестницу, которая неправильная, но не сломанная.
Какой столбец в ваших собственных данных вам меньше всего хотелось бы узнать, что в течение месяца он был незаметно сгруппирован неправильно?
SQL для аналитиков составляет 458 страниц, CASE читается по ветке, включая то, что происходит со строками, которые не улавливает ни одна ветка.
SQL для аналитиков, 19 $ →тот Курс SQL обучает основам аналитического SQL на рабочих примерах, практике, флеш-карточках и пробном экзамене. Все это работает в вашем браузере, и вам не нужно ничего устанавливать.
Откройте набор SQL →Или приступайте к делу и учитесь, написав запросы: открыть SQL-практикум, тринадцать запросов, каждый из которых добавляет что-то одно к последнему.