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'