Повечето основни 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'