De fleste større RDBMS'er understøtter NULLIF()
operator, som returnerer NULL
hvis begge dets argumenter er ækvivalente. Hvis argumenterne ikke er ækvivalente, NULLIF()
returnerer det første argument.
NULLIF()
er en SQL-standardfunktion (den er inkluderet i ISO/IEC 9075-specifikationen).
Syntaks
Syntaksen ser sådan ud:
NULLIF (V1, V2)
Dette svarer til følgende CASE
udtryk:
CASE WHEN V1=V2 THEN NULL ELSE V1 END
Eksempel
Her er et eksempel til demonstration:
SELECT NULLIF( 12, 12 );
Resultat:
NULL
I dette tilfælde er begge argumenter identiske, så resultatet er NULL
.
Afhængigt af dit RDBMS kan det faktiske output for NULL-værdier være anderledes. For eksempel, når du bruger psql (til PostgreSQL), udlæses den tomme streng som standard, når en NULL-værdi returneres (selvom dette kan ændres). Det er det samme med SQLite (og dette kan også ændres).
Når argumenterne ikke er ækvivalente
Her er, hvad der sker, når argumenterne ikke er ækvivalente:
SELECT NULLIF( 12, 13 );
Resultat:
12
Argumenterne er forskellige, og derfor returneres det første argument.
Strenge
Her er et eksempel, der sammenligner strenge:
SELECT
NULLIF( 'Gym', 'Gym' ) AS "Same",
NULLIF( 'Gym', 'Bag' ) AS "Different";
Resultat:
+------+-----------+ | Same | Different | +------+-----------+ | NULL | Gym | +------+-----------+
Datoer
Her er et eksempel, der sammenligner datoer:
SELECT
NULLIF( DATE '2045-11-25', DATE '2045-11-25' ) AS "Same",
NULLIF( DATE '2045-11-25', DATE '1990-08-15' ) AS "Different";
Resultat:
+------+------------+ | Same | Different | +------+------------+ | NULL | 2045-11-25 | +------+------------+
Udtryk
NULLIF()
evaluerer den aktuelle værdi af udtrykkene. Derfor, hvis vi sender et udtryk som dette:
SELECT NULLIF( 24, 2 * 12 );
Vi får dette:
NULL
2 ganget med 12 er 24, så de to argumenter er ækvivalente.
Her er, hvad der sker, hvis vi ændrer det andet argument:
SELECT NULLIF( 24, 3 * 12 );
Resultat:
24
Det første argument returneres.
Et databaseeksempel
Antag, at vi kører følgende forespørgsel:
SELECT
Name,
LocalName
FROM country
WHERE Region = 'South America'
ORDER BY Name;
Resultat:
+------------------+-------------------+ | 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 | +------------------+-------------------+
Her har vi landenavne i venstre kolonne, og det lokale navn for det respektive land i højre.
Lad os tilføje NULLIF()
til en tredje kolonne i vores forespørgsel:
SELECT
Name,
LocalName,
NULLIF(LocalName, Name) AS "Local Name if Different"
FROM country
WHERE Region = 'South America'
ORDER BY Name;
Resultat:
+------------------+-------------------+-------------------------+ | 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 | +------------------+-------------------+-------------------------+
Vi kan se, at den tredje kolonne kun returnerer det lokale navn, hvis det er forskelligt fra værdien i Name
kolonne. Hvis det er det samme, så NULL
er returneret.
Vi kan også bruge NULLIF()
for at filtrere vores forespørgselsresultater:
SELECT
Name,
LocalName
FROM country
WHERE Region = 'South America'
AND NULLIF(LocalName, Name) IS NOT NULL
ORDER BY Name;
Resultat:
+---------------+-------------------+ | Name | LocalName | +---------------+-------------------+ | Brazil | Brasil | | French Guiana | Guyane française | | Peru | Perú/Piruw | +---------------+-------------------+
I dette tilfælde returnerede vi kun de rækker, hvor det lokale navn er forskelligt fra Name
kolonne.
NULLIF()
vs CASE
Som nævnt er følgende kode:
NULLIF (V1, V2)
svarer til følgende CASE
udtryk:
CASE WHEN V1=V2 THEN NULL ELSE V1 END
Så det er muligt at bruge en CASE
udtryk i stedet for NULLIF()
hvis det ønskes. NULLIF()
funktion er grundlæggende en syntaktisk genvej til CASE
udtryk.
Så for eksempel kunne vi erstatte det forrige eksempel med følgende:
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;
Resultat:
+---------------+-------------------+ | Name | LocalName | +---------------+-------------------+ | Brazil | Brasil | | French Guiana | Guyane française | | Peru | Perú/Piruw | +---------------+-------------------+
Men NULLIF()
funktion er meget mere kortfattet.
Forkert parameterantal
Sender det forkerte antal argumenter, resulterer det i en fejl:
SELECT NULLIF( 'One' );
Resultat i MySQL:
ERROR 1582 (42000): Incorrect parameter count in the call to native function 'NULLIF'