NULL: nuair nach bhfuil luach ann ar chor ar bith
What you'll learn
NULLa aithint thar nialas agus thar shraith fholamh agus é a thástáil tríIS NULL/IS NOT NULL- an loighic thrí-luachach a mhíniú: cén fáth a dtugann
x = NULLagus nach ligeannWHEREa leithéid de shraith tríd - an chúis a aimsiú le haschur folamh ó
NOT INle liosta ina bhfuilNULLi bhfolach - luachanna cúltaca a chur isteach san aschur trí
COALESCE, gan na sonraí sa tábla a athrú
Ciallaíonn NULL «anaithnid»
I holagraim na sean-chartlann bíonn poill: ní lasann cill, agus feiceann tú an dorchadas tríthi. Ní damáiste é seo ná lorg caomhnaithe. Tá an chartlann macánta: san áit nach raibh an freagra ar eolas aici, níor chum sí é. Ní hionann «níl a fhios agam» agus «níl».
Ní nialas é NULL agus ní sraith fholamh é, ach easpa luacha. In «Kotomarket» d’fhéadfadh sé breathnú mar, abair, cathair úsáideora nár líonadh isteach. Ní láimhseálann SQL é mar ghnáthluach, mar sin ní thugann an slonn x = NULL TRUE ná FALSE ach — an tríú freagra den loighic thrí-luachach.
Sin an fáth a ndéanann tú tástáil mar seo:
colún IS NULL— tá an luach in easnamh;colún IS NOT NULL— tá an luach ann.
Má bhreathnaíonn poll san aschur rómhistéireach, cuir téacs cúltaca isteach trí COALESCE(colún, cúltaca). Ní dheisíonn sé seo na sonraí sa tábla, ní dhéanann sé ach an t-aschur a chóiriú go néata — cosúil le cárta «níl aon sonraí» ar sheilf fholamh.
QUERY: Tabhair urraim do na poill sa chuimhne. Tá bunachar a deir go macánta «níl a fhios agam» níos iontaofa ná bunachar a insíonn bréag go muiníneach.
NULL, ноль и пустая строка — это разные вещи
Новички часто воспринимают NULL как «пустоту», а потом удивляются, почему запросы работают странно.
Разберём на простом примере.
Допустим, в таблице products есть столбец discount_percent:
| id | title | discount_percent |
|---|---|---|
| 1 | Корм «Лунный тунец» | 10 |
| 2 | Миска антигравитационная | 0 |
| 3 | Лежанка архивиста |
Что означает каждая строка?
У первого товара скидка 10%.
У второго товара скидка 0%. Это значит: скидка известна, она равна нулю.
У третьего товара стоит NULL. Это значит: мы не знаем скидку, она не указана, не рассчитана или пока не загружена.
То есть:
discount_percent = 0
и
discount_percent IS NULL
— это разные состояния.
То же самое с текстом.
city = ''
означает: город указан как пустая строка.
city IS NULL
означает: города в ячейке вообще нет.
В реальных базах это важно. Например, пустая строка может появиться из формы, где пользователь стёр текст и отправил поле пустым. А NULL может означать, что поле вообще не заполняли, данные ещё не пришли из другого сервиса или значение действительно неизвестно.
NULL ann. Ní sraith fholamh ná nialas é, ach easpa luacha.Почему = NULL не работает
Теперь главный подвох.
Кажется, что если мы хотим найти пользователей без города, можно написать так:
SELECT id, name, city
FROM users
WHERE city = NULL;
Но такой запрос не найдёт строки с NULL.
Причина в том, что NULL — это не обычное значение. Его нельзя сравнивать через = так же, как число или строку.
SQL рассуждает примерно так:
city = 'Москва'
Можно проверить. Если в city лежит 'Москва', ответ TRUE. Если лежит 'Казань', ответ FALSE.
А вот так:
city = NULL
SQL не может ответить TRUE или FALSE, потому что NULL означает «значение неизвестно».
Если город неизвестен, можно ли сказать, что он равен NULL? Нет.
Можно ли сказать, что он не равен NULL? Тоже нет.
Ответ SQL: .
То есть «неизвестно».
В SQL есть не только два логических результата:
TRUE
FALSE
Есть ещё третий:
UNKNOWN
Это называется трёхзначная логика.
NULL trí = nó <> an tríú ceann, agus ní ligeann WHERE a leithéid de shraith tríd.NULL ведут себя особенно. Обычные операторы = и <> не дают ни TRUE, ни FALSE: результатом становится NULL в выдаче, то есть логическое UNKNOWN.| eq_null | neq_null | null_eq_null | is_null |
|---|---|---|---|
| true |
WHERE пропускает только TRUE
Теперь важный шаг.
WHERE оставляет строку только тогда, когда условие вернуло TRUE.
Если условие вернуло FALSE, строка отбрасывается.
Если условие вернуло UNKNOWN, строка тоже отбрасывается.
То есть для WHERE работает правило:
| Результат условия | Строка попадёт в результат? |
|---|---|
| TRUE | да |
| FALSE | нет |
| нет |
Именно поэтому запрос:
SELECT id, name, city
FROM users
WHERE city = NULL;
не возвращает пользователей без города.
Для строки, где city равен NULL, выражение:
city = NULL
даёт не TRUE, а UNKNOWN.
А WHERE пропускает только TRUE.
Как правильно проверять NULL
Для NULL есть специальные проверки:
столбец IS NULL
и
столбец IS NOT NULL
Если нужно найти пользователей, у которых город не указан:
SELECT id, name, city
FROM users
WHERE city IS NULL;
Если нужно найти пользователей, у которых город указан:
SELECT id, name, city
FROM users
WHERE city IS NOT NULL;
Запомни главное правило:
-- неправильно
WHERE city = NULL
-- неправильно
WHERE city <> NULL
-- правильно
WHERE city IS NULL
-- правильно
WHERE city IS NOT NULL
IS NULL не сравнивает значение с NULL. Он задаёт другой вопрос:
В этой ячейке значение отсутствует?
А IS NOT NULL спрашивает:
В этой ячейке значение есть?
IS NULL и IS NOT NULL — правильный способ фильтровать строки по отсутствию или наличию значения.Почему <> тоже может удивить
Ещё один частый баг появляется с оператором <>.
Допустим, нужно найти всех пользователей не из Москвы.
Новичок пишет:
SELECT id, name, city
FROM users
WHERE city <> 'Москва';
Кажется, что запрос должен вернуть:
- пользователей из Казани
- пользователей из других городов
- пользователей, у которых город не указан
Но строки с NULL в результат не попадут.
Почему?
Для строки с городом 'Казань':
city <> 'Москва'
даёт TRUE.
Для строки с городом 'Москва':
city <> 'Москва'
даёт FALSE.
Для строки с NULL:
city <> 'Москва'
даёт UNKNOWN.
А WHERE пропускает только TRUE.
Поэтому строка с неизвестным городом отбрасывается.
Чтобы включить пользователей, у которых город не указан, нужно явно добавить условие:
SELECT id, name, city
FROM users
WHERE city <> 'Москва'
OR city IS NULL;
Теперь логика такая:
Покажи всех, у кого город не Москва, а также тех, у кого город вообще не указан.
В PostgreSQL есть ещё удобный оператор:
WHERE city IS DISTINCT FROM 'Москва'
Он обращается с NULL более предсказуемо и возвращает строго TRUE или FALSE.
Например:
NULL IS DISTINCT FROM 'Москва'
вернёт TRUE.
А:
NULL IS NOT DISTINCT FROM NULL
вернёт TRUE.
Но базовое правило для новичка остаётся таким: если нужно работать с отсутствующим значением, используй IS NULL и IS NOT NULL.
<> не включает строки с NULL, потому что сравнение с неизвестным значением даёт UNKNOWN.| id | full_name | city |
|---|---|---|
| 1 | Артём Волков | Санкт-Петербург |
| 2 | Екатерина Алексеев | Екатеринбург |
| 3 | Николай Никитин | Алматы |
| 4 | Екатерина Иванов | Новосибирск |
| 5 | Елена Петров | Казань |
| 6 | Ирина Кузнецов | Новосибирск |
| 7 | Наталья Смирнов | Нижний Новгород |
| 8 | Николай Зайцев | Новосибирск |
| 10 | Алексей Лебедев | Екатеринбург |
| 11 | Дмитрий Козлов | Алматы |
| 12 | Павел Смирнов | Нижний Новгород |
| 13 | Алексей Лебедев | Санкт-Петербург |
| 14 | Анна Никитин | Нижний Новгород |
| 15 | Екатерина Макаров | Казань |
| 18 | Дмитрий Иванов | Минск |
| 19 | Светлана Волков | Новосибирск |
| 20 | Ирина Орлов | Санкт-Петербург |
| 22 | Ирина Петров | Екатеринбург |
| 23 | Светлана Соколов | Екатеринбург |
| 24 | Елена Зайцев | Санкт-Петербург |
Осторожно с NOT, AND и OR
NULL особенно часто ломает ожидания в сложных условиях.
Посмотри на условие:
WHERE NOT (city = 'Москва')
На первый взгляд оно похоже на:
WHERE city <> 'Москва'
И действительно, для обычных значений результат будет похож.
Но если city равен NULL, выражение:
city = 'Москва'
даёт UNKNOWN.
А теперь важный момент:
NOT UNKNOWN
тоже даёт UNKNOWN.
Не TRUE.
Поэтому строка с NULL всё равно не попадёт в результат.
Пример:
SELECT id, name, city
FROM users
WHERE NOT (city = 'Москва');
Строки с неизвестным городом не пройдут.
Чтобы включить их, нужно писать явно:
SELECT id, name, city
FROM users
WHERE city <> 'Москва'
OR city IS NULL;
Это правило стоит запомнить:
NOTне превращаетUNKNOWNвTRUE.
В SQL UNKNOWN остаётся неизвестностью даже после отрицания.
COALESCE: запасной свет для прорех
Иногда NULL в данных — нормальная ситуация, но в отчёте его неудобно показывать пользователю.
Например:
SELECT id, name, city
FROM users;
Результат:
| id | name | city |
|---|---|---|
| 1 | Анна | Москва |
| 2 | Борис |
Для внутренней базы NULL понятен. Но в интерфейсе или отчёте лучше показать человеку нормальную подпись:
город не указан
Для этого используют COALESCE.
COALESCE возвращает первый аргумент, который не равен NULL.
SELECT COALESCE(NULL, NULL, 'запасной вариант');
Результат:
| coalesce |
|---|
| запасной вариант |
Применим к таблице:
SELECT
id,
name,
COALESCE(city, 'город не указан') AS city_for_report
FROM users;
Результат:
| id | name | city_for_report |
|---|---|---|
| 1 | Анна | Москва |
| 2 | Борис | город не указан |
| 3 | Вера | Казань |
Важно: COALESCE не меняет данные в таблице.
Он меняет только выдачу запроса.
То есть в таблице у Бориса по-прежнему хранится NULL. Просто в результате запроса мы показываем вместо него понятный текст.
Это похоже на табличку на пустой витрине: не товар появился, а объяснение для зрителя.
COALESCE помогает заменить NULL запасным значением в результате запроса, не меняя исходные данные.| id | full_name | city |
|---|---|---|
| 1 | Артём Волков | Санкт-Петербург |
| 2 | Екатерина Алексеев | Екатеринбург |
| 3 | Николай Никитин | Алматы |
| 4 | Екатерина Иванов | Новосибирск |
| 5 | Елена Петров | Казань |
| 6 | Ирина Кузнецов | Новосибирск |
| 7 | Наталья Смирнов | Нижний Новгород |
| 8 | Николай Зайцев | Новосибирск |
| 9 | Ирина Козлов | Москва |
| 10 | Алексей Лебедев | Екатеринбург |
| 11 | Дмитрий Козлов | Алматы |
| 12 | Павел Смирнов | Нижний Новгород |
| 13 | Алексей Лебедев | Санкт-Петербург |
| 14 | Анна Никитин | Нижний Новгород |
| 15 | Екатерина Макаров | Казань |
| 16 | Елена Козлов | Москва |
| 17 | Наталья Макаров | Москва |
| 18 | Дмитрий Иванов | Минск |
| 19 | Светлана Волков | Новосибирск |
| 20 | Ирина Орлов | Санкт-Петербург |
COALESCE может выбирать из нескольких вариантов
COALESCE принимает не два аргумента, а сколько угодно.
Он идёт слева направо и возвращает первый аргумент, который не NULL.
Например, в таблице пользователей могут быть разные способы связи:
| id | name | telegram | phone | |
|---|---|---|---|---|
| 1 | Анна | @anna | anna@mail.test | |
| 2 | Борис | NULL | boris@mail.test | NULL |
| 3 | Вера | NULL | NULL | +7001 |
Мы хотим показать лучший доступный контакт: сначала Telegram, если он есть; если нет — email; если нет — телефон; если нет ничего — текст «нет контакта».
SELECT
id,
name,
COALESCE(telegram, email, phone, 'нет контакта') AS best_contact
FROM users;
Результат:
| id | name | best_contact |
|---|---|---|
| 1 | Анна | @anna |
| 2 | Борис | boris@mail.test |
| 3 | Вера | +7001 |
Логика такая:
возьми telegram
если telegram NULL — возьми email
если email NULL — возьми phone
если phone NULL — возьми 'нет контакта'
Это очень частый паттерн в отчётах, выгрузках и интерфейсах.
Важный технический момент: аргументы COALESCE должны быть совместимы по типам.
Так можно:
COALESCE(city, 'город не указан')
Потому что оба варианта — текст.
А вот так может быть ошибка:
COALESCE(discount_percent, 'нет скидки')
Если discount_percent — число, а 'нет скидки' — текст, базе может быть непонятно, какой тип результата нужен.
Обычно в таких случаях число сначала явно превращают в текст:
COALESCE(discount_percent::text, 'нет скидки')
NULL в SELECT и NULL в WHERE — разные ощущения
Важно различать две ситуации.
В SELECT ты можешь увидеть NULL в результате:
SELECT id, name, city
FROM users;
Здесь NULL просто выводится как значение ячейки в результате. В разных SQL-редакторах он может выглядеть по-разному: как NULL, как пустая ячейка или как специальная метка.
А вот в WHERE NULL влияет на фильтрацию:
SELECT id, name, city
FROM users
WHERE city <> 'Москва';
Здесь строка с NULL может исчезнуть из результата, потому что условие стало UNKNOWN.
То есть SELECT показывает данные, а WHERE решает, пропускать строку или нет.
Для WHERE важно не то, как красиво выглядит ячейка, а вернуло ли условие строго TRUE.
Частые ошибки с NULL
Ошибка 1. Искать NULL через =
WHERE city = NULL
Так не нужно писать. Это условие не найдёт строки с NULL.
Правильно:
WHERE city IS NULL
Ошибка 2. Искать заполненные значения через <> NULL
WHERE city <> NULL
Так тоже не нужно писать. Это условие не найдёт заполненные строки.
Правильно:
WHERE city IS NOT NULL
Ошибка 3. Думать, что <> включает NULL
WHERE city <> 'Москва'
Этот запрос найдёт города, которые точно не равны Москве. Но строки, где город неизвестен, он не вернёт.
Если нужны и «не Москва», и «город не указан»:
WHERE city <> 'Москва'
OR city IS NULL
Ошибка 4. Путать пустую строку и NULL
WHERE city = ''
Это ищет пустую строку, а не NULL.
Чтобы найти оба варианта:
WHERE city = ''
OR city IS NULL
Иногда в грязных данных приходится проверять и то, и другое.
Ошибка 5. Использовать COALESCE и думать, что данные изменились
SELECT COALESCE(city, 'город не указан') AS city
FROM users;
Этот запрос только меняет отображение результата.
Он не записывает 'город не указан' в таблицу.
Чтобы реально изменить данные, нужен UPDATE, но это уже отдельная операция и отдельная ответственность.
Главное правило урока
NULL нельзя проверять через обычные сравнения.
Пиши так:
WHERE column IS NULL
или так:
WHERE column IS NOT NULL
Не пиши так:
WHERE column = NULL
и так:
WHERE column <> NULL
WHERE пропускает только строки, где условие вернуло TRUE.
FALSE и UNKNOWN в результат не проходят.
Interview question
Ceist agallaimh: cén fáth nach dtabharfaidh WHERE city <> 'Москва' na sraitheanna ina bhfuil an chathair folamh ar ais, agus conas a chuireann tú san áireamh iad sa toradh?
Freagra láidir: tugann NULL <> 'Москва' , agus ní ligeann WHERE ach TRUE tríd — gearrann = agus <> araon na sraitheanna amach. Chun iad a chur san áireamh scríobhann tú WHERE city <> 'Москва' OR city IS NULL, nó in PostgreSQL WHERE city IS DISTINCT FROM 'Москва': caitheann an t-oibreoir sin le NULL mar ghnáthluach agus tugann sé TRUE nó FALSE go cruinn ar ais.
Ceist agallaimh: cén difríocht atá idir NULL agus nialas agus sraith fholamh?
Freagra láidir: is luachanna iad nialas agus an tsraith fholamh: tá siad cothrom leo féin agus glacann siad páirt i gcomparáidí. Is é NULL an marc «níl luach ann»: tugann aon chomparáid leis trí =/<> UNKNOWN, fiú NULL = NULL; ní féidir é a sheiceáil ach trí IS NULL/IS NOT NULL. Scéal ar leith is ea Oracle, áit a stóráiltear sraith fholamh in VARCHAR2 mar NULL — foinse chlasaiceach fabhtanna agus cód á aistriú.
NULL = NULL?WHERE?COALESCE(city, 'город не указан')?КВЕРИ: Пустота тоже говорит. Главное — не заставлять её притворяться значением.
- Drop Unrated Reviews, Replace Empty CommentsEASY
- Cé a Mhol Gach Custaiméir a AimsiúEASY
- Páirteanna neamhchríochnaithe: Leagan eileEASY