Повечето основни RDBMS поддържат NULLIF() оператор, който връща NULL ако и двата му аргумента са еквивалентни. Ако аргументите не са еквивалентни, NULLIF() връща първия аргумент.
NULLIF() е стандартна функция на SQL (включена е в спецификацията ISO/IEC 9075).
Синтаксис
Синтаксисът е така:
NULLIF (V1, V2)
Това е еквивалентно на следния CASE израз:
CASE WHEN V1=V2 THEN NULL ELSE V1 END Пример
Ето пример за демонстрация:
SELECT NULLIF( 12, 12 ); Резултат:
NULL
В този случай и двата аргумента са идентични и резултатът е NULL .
В зависимост от вашата RDBMS, действителният изход за NULL стойности може да е различен. Например, когато използвате psql (за PostgreSQL), празният низ се извежда по подразбиране всеки път, когато се върне стойност NULL (въпреки че това може да бъде променено). Същото е и със SQLite (и това също може да бъде променено).
Когато аргументите не са еквивалентни
Ето какво се случва, когато аргументите не са еквивалентни:
SELECT NULLIF( 12, 13 ); Резултат:
12
Аргументите са различни и така се връща първият аргумент.
Стрингове
Ето пример, който сравнява низове:
SELECT
NULLIF( 'Gym', 'Gym' ) AS "Same",
NULLIF( 'Gym', 'Bag' ) AS "Different"; Резултат:
+------+-----------+ | Same | Different | +------+-----------+ | NULL | Gym | +------+-----------+
Дати
Ето пример, който сравнява датите:
SELECT
NULLIF( DATE '2045-11-25', DATE '2045-11-25' ) AS "Same",
NULLIF( DATE '2045-11-25', DATE '1990-08-15' ) AS "Different"; Резултат:
+------+------------+ | Same | Different | +------+------------+ | NULL | 2045-11-25 | +------+------------+
Изрази
NULLIF() оценява текущата стойност на изразите. Следователно, ако предадем израз като този:
SELECT NULLIF( 24, 2 * 12 ); Получаваме това:
NULL
2, умножено по 12, е 24, така че двата аргумента са еквивалентни.
Ето какво се случва, ако променим втория аргумент:
SELECT NULLIF( 24, 3 * 12 ); Резултат:
24
Първият аргумент се връща.
Пример за база данни
Да предположим, че изпълняваме следната заявка:
SELECT
Name,
LocalName
FROM country
WHERE Region = 'South America'
ORDER BY Name; Резултат:
+------------------+-------------------+ | Name | LocalName | +------------------+-------------------+ | Argentina | Argentina | | Bolivia | Bolivia | | Brazil | Brasil | | Chile | Chile | | Colombia | Colombia | | Ecuador | Ecuador | | Falkland Islands | Falkland Islands | | French Guiana | Guyane française | | Guyana | Guyana | | Paraguay | Paraguay | | Peru | Perú/Piruw | | Suriname | Suriname | | Uruguay | Uruguay | | Venezuela | Venezuela | +------------------+-------------------+
Тук имаме имена на държави в лявата колона, а местното име за съответната държава в дясната.
Нека добавим NULLIF() към трета колона на нашата заявка:
SELECT
Name,
LocalName,
NULLIF(LocalName, Name) AS "Local Name if Different"
FROM country
WHERE Region = 'South America'
ORDER BY Name; Резултат:
+------------------+-------------------+-------------------------+ | Name | LocalName | Local Name if Different | +------------------+-------------------+-------------------------+ | Argentina | Argentina | NULL | | Bolivia | Bolivia | NULL | | Brazil | Brasil | Brasil | | Chile | Chile | NULL | | Colombia | Colombia | NULL | | Ecuador | Ecuador | NULL | | Falkland Islands | Falkland Islands | NULL | | French Guiana | Guyane française | Guyane française | | Guyana | Guyana | NULL | | Paraguay | Paraguay | NULL | | Peru | Perú/Piruw | Perú/Piruw | | Suriname | Suriname | NULL | | Uruguay | Uruguay | NULL | | Venezuela | Venezuela | NULL | +------------------+-------------------+-------------------------+
Можем да видим, че третата колона връща локалното име само ако е различно от стойността в Name колона. Ако е същото, тогава NULL се връща.
Можем също да използваме NULLIF() за филтриране на резултатите от нашите заявки:
SELECT
Name,
LocalName
FROM country
WHERE Region = 'South America'
AND NULLIF(LocalName, Name) IS NOT NULL
ORDER BY Name; Резултат:
+---------------+-------------------+ | Name | LocalName | +---------------+-------------------+ | Brazil | Brasil | | French Guiana | Guyane française | | Peru | Perú/Piruw | +---------------+-------------------+
В този случай върнахме само онези редове, където локалното име е различно от Name колона.
NULLIF() срещу CASE
Както споменахме, следният код:
NULLIF (V1, V2)
е еквивалентен на следния CASE израз:
CASE WHEN V1=V2 THEN NULL ELSE V1 END
Така че е възможно да се използва CASE израз вместо NULLIF() ако желаете. NULLIF() функцията е основно синтактичен пряк път за CASE израз.
Така например бихме могли да заменим предишния пример със следното:
SELECT
Name,
LocalName
FROM country
WHERE Region = 'South America'
AND (CASE WHEN LocalName = Name THEN NULL ELSE LocalName END) IS NOT NULL
ORDER BY Name; Резултат:
+---------------+-------------------+ | Name | LocalName | +---------------+-------------------+ | Brazil | Brasil | | French Guiana | Guyane française | | Peru | Perú/Piruw | +---------------+-------------------+
Въпреки това, NULLIF() функцията е много по-сбита.
Неправилен брой параметри
Предаването на грешен брой аргументи води до грешка:
SELECT NULLIF( 'One' ); Резултат в MySQL:
ERROR 1582 (42000): Incorrect parameter count in the call to native function 'NULLIF'