Към съдържанието
wannacode

CASE и липсващите стойности

Накратко: CASE WHEN връща различна стойност според условие, COALESCE слага стойност на мястото на NULL, а NULLIF превръща дадена стойност в NULL.

Проблем

Платена, а не paid

На страницата „Моите поръчки“ клиентът вижда състоянието както е в базата: paid, shipped. Кодовете на английски са удобни за програмата, но клиентът очаква „платена“ и „изпратена“.

Сайтът иска и филтър „евтини, средни, скъпи“. В базата няма такава колона, има само цена.

Идеята

CASE WHEN

CASE дава различна стойност според условие:

SQLбаза: магазин

Условията се проверяват отгоре надолу. Първото вярно WHEN дава стойността на THEN до него, и останалите не се гледат. ELSE е за всички, за които нищо не е вярно. END затваря израза, а AS му дава име.

Когато сравняваш една колона с няколко стойности, има по-кратък запис: колоната се пише веднъж след CASE, а след всяко WHEN стои само стойността:

SQLбаза: магазин

Пробвай

Състоянията с думи

Покажи номера, датата и състоянието с думи на всяка поръчка, в колона status_text: new е „нова“, paid е „платена“, shipped е „изпратена“, delivered е „доставена“, cancelled е „отказана“.

SQLбаза: магазин

Виж го

Скъпите изчезнаха

Колега пренаписва ценовите групи с >. Пусни и виж кухнята:

SQLбаза: магазин
1. Защо тиганът за 24,90 € излезе „среден“?

Още нещо: ако няма ELSE, а нито едно WHEN не е вярно, резултатът е NULL. Хлябът има бележка само когато е изчерпан или е малко:

SQLбаза: магазин

Понякога точно това искаш. Ако не, напиши ELSE.

Идеята

COALESCE и NULLIF

COALESCE(a, b, …) връща първата стойност, която не е NULL. Така се слага дума на мястото на липсващото:

SQLбаза: магазин

Понякога „липсва“ е записано не като NULL, а като празен текст. В двата примера отдолу базата има още един клиент, Анна, записана през формуляр, който праща '' вместо NULL. COALESCE не я хваща, защото празният текст е стойност:

SQLбаза: магазин

NULLIF(a, b) дава NULL, когато a е равно на b, иначе дава a. Така празният текст става NULL, а COALESCE хваща и двамата:

SQLбаза: магазин
По-точно, за любопитните

NULLIF се ползва и за делене: total / NULLIF(count, 0). Когато count е 0, делителят става NULL и резултатът е NULL. В SQLite делението на нула и без това дава NULL, но в PostgreSQL е грешка и спира цялата заявка.

Пробвай

Редът за куриера

Поправи реда „име, град“ от урока за текст: когато градът липсва, на мястото му да пише „без град“. Колоната да се казва contact.

SQLбаза: магазин

Упражнение

Две задачи

1. До всеки продукт сайтът пише наличността с думи: „изчерпан“ при 0, „последни бройки“ под 10, иначе „в наличност“. Покажи името, наличността и думите в колона availability.

Наличността с думи за всеки продукт:

SQLбаза: магазин

2. Складът работи в този ред: първо опакова платените (paid), после гледа новите (new), накрая проверява изпратените (shipped). Покажи номера, състоянието и датата на тези поръчки в реда на работа, а в едно състояние първо най-старата. При една и съща дата първо по-малкият номер.

Отворените поръчки в реда, в който складът ги обработва:

SQLбаза: магазин
По-точно, за любопитните

SQLite има и IIF(условие, ако е вярно, ако не е): кратък CASE с едно WHEN и ELSE. Има го и в SQL Server, но не и в PostgreSQL. CASE е стандартният запис и работи навсякъде.

SQLбаза: магазин

Тест

Провери се

1. Какво дава CASE, когато нито едно WHEN не е вярно и няма ELSE?
2. Какво връща COALESCE(NULL, NULL, 'София', 'Варна')?
3. Какво връща NULLIF(city, '') за град, който е празен текст?
4. Къде може да стои CASE?

Създаден от Иво Гергов като част от кампанията на Evo Tech за достъпно обучение по програмиране ·