Większość głównych RDBMS-ów obsługuje NULLIF() operator, który zwraca NULL jeśli oba jego argumenty są równoważne. Jeśli argumenty nie są równoważne, NULLIF() zwraca pierwszy argument.
NULLIF() jest standardową funkcją SQL (zawartą w specyfikacji ISO/IEC 9075).
Składnia
Składnia wygląda tak:
NULLIF (V1, V2)
Jest to równoważne następującemu CASE wyrażenie:
CASE WHEN V1=V2 THEN NULL ELSE V1 END Przykład
Oto przykład do zademonstrowania:
SELECT NULLIF( 12, 12 ); Wynik:
NULL
W tym przypadku oba argumenty są identyczne, więc wynikiem jest NULL .
W zależności od RDBMS rzeczywiste dane wyjściowe dla wartości NULL mogą być różne. Na przykład podczas korzystania z psql (dla PostgreSQL), pusty ciąg jest domyślnie wyprowadzany za każdym razem, gdy zwracana jest wartość NULL (chociaż można to zmienić). Tak samo jest z SQLite (i to również można zmienić).
Kiedy argumenty nie są równoważne
Oto, co się dzieje, gdy argumenty nie są równoważne:
SELECT NULLIF( 12, 13 ); Wynik:
12
Argumenty są różne, dlatego zwracany jest pierwszy argument.
Struny
Oto przykład porównujący ciągi:
SELECT
NULLIF( 'Gym', 'Gym' ) AS "Same",
NULLIF( 'Gym', 'Bag' ) AS "Different"; Wynik:
+------+-----------+ | Same | Different | +------+-----------+ | NULL | Gym | +------+-----------+
Daty
Oto przykład porównujący daty:
SELECT
NULLIF( DATE '2045-11-25', DATE '2045-11-25' ) AS "Same",
NULLIF( DATE '2045-11-25', DATE '1990-08-15' ) AS "Different"; Wynik:
+------+------------+ | Same | Different | +------+------------+ | NULL | 2045-11-25 | +------+------------+
Wyrażenia
NULLIF() ocenia bieżącą wartość wyrażeń. Dlatego jeśli przekażemy takie wyrażenie:
SELECT NULLIF( 24, 2 * 12 ); Otrzymujemy to:
NULL
2 pomnożone przez 12 daje 24, więc te dwa argumenty są równoważne.
Oto, co się stanie, jeśli zmienimy drugi argument:
SELECT NULLIF( 24, 3 * 12 ); Wynik:
24
Zwracany jest pierwszy argument.
Przykład bazy danych
Załóżmy, że uruchamiamy następujące zapytanie:
SELECT
Name,
LocalName
FROM country
WHERE Region = 'South America'
ORDER BY Name; Wynik:
+------------------+-------------------+ | 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 | +------------------+-------------------+
Tutaj mamy nazwy krajów w lewej kolumnie, a lokalną nazwę odpowiedniego kraju w prawej.
Dodajmy NULLIF() do trzeciej kolumny naszego zapytania:
SELECT
Name,
LocalName,
NULLIF(LocalName, Name) AS "Local Name if Different"
FROM country
WHERE Region = 'South America'
ORDER BY Name; Wynik:
+------------------+-------------------+-------------------------+ | 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 | +------------------+-------------------+-------------------------+
Widzimy, że trzecia kolumna zwraca nazwę lokalną tylko wtedy, gdy jest inna niż wartość w Name kolumna. Jeśli jest taki sam, to NULL jest zwracany.
Możemy również użyć NULLIF() aby filtrować wyniki naszych zapytań:
SELECT
Name,
LocalName
FROM country
WHERE Region = 'South America'
AND NULLIF(LocalName, Name) IS NOT NULL
ORDER BY Name; Wynik:
+---------------+-------------------+ | Name | LocalName | +---------------+-------------------+ | Brazil | Brasil | | French Guiana | Guyane française | | Peru | Perú/Piruw | +---------------+-------------------+
W tym przypadku zwróciliśmy tylko te wiersze, w których nazwa lokalna jest inna niż Name kolumna.
NULLIF() vs CASE
Jak wspomniano, następujący kod:
NULLIF (V1, V2)
jest odpowiednikiem następującego CASE wyrażenie:
CASE WHEN V1=V2 THEN NULL ELSE V1 END
Więc możliwe jest użycie CASE wyrażenie zamiast NULLIF() jeśli jest taka potrzeba. NULLIF() funkcja jest w zasadzie skrótem składniowym dla CASE wyrażenie.
Na przykład możemy zastąpić poprzedni przykład następującym:
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; Wynik:
+---------------+-------------------+ | Name | LocalName | +---------------+-------------------+ | Brazil | Brasil | | French Guiana | Guyane française | | Peru | Perú/Piruw | +---------------+-------------------+
Jednak NULLIF() funkcja jest znacznie bardziej zwięzła.
Nieprawidłowa liczba parametrów
Przekazanie niewłaściwej liczby argumentów skutkuje błędem:
SELECT NULLIF( 'One' ); Wynik w MySQL:
ERROR 1582 (42000): Incorrect parameter count in the call to native function 'NULLIF'