Overview
Η χρήση των δεδομένων στην εποχή μας έχει οδηγήσει τους περισσότερους να μάθουν να γράφουν queries για να μπορούν να ικανοποιήσουν τις ανάγκες τους.
Στις περισσότερες των περιπτώσεων αυτά τα queries κάνουν χρήση των βασικών στοιχείων που έχει η σύνταξη του statement. Αυτό πάντα όμως δεν είναι το ιδανικό.
Σε αυτό το άρθρο θα αναφερθώ στο NULLIF expression το οποίο αν χρησιμοποιηθεί κατάλληλα μπορεί να δώσει πολλαπλά κέρδη τόσο στην απλότητα του query όσο και στην απόδοση του.
NOTE
Aρκετοί το αναφέρουν σαν statement αλλά δεν είναι. Είναι expression. Όπως δεν είναι statement η CASE, είναι και αυτή expression.
NOTE
Υποστηρίζεται σε SQL Server, Azure SQL Database, Azure Synapse Analytics (SQL DW) και Parallel Data Warehouse.
Αν και η ύπαρξη του χάνεται στο παρελθόν, η χρήση του είναι ελάχιστη, καθώς αρκετοί δεν ξέρουν ότι υπάρχει και άλλοι δεν έχουν βρει ακόμα το πως μπορούν να το χρησιμοποιήσουν.
NULLIF expression
Το τι κάνει η NULLIF είναι απλό. Παίρνει δύο ορίσματα και ελέγχει αυτά αν είναι ίσα. Αν είναι, επιστρέφει null, αλλιώς επιστρέφει την τιμή του πρώτου ορίσματος.
Διαβάζοντας την παραπάνω παράγραφο είμαι σίγουρος ότι κάποιος θα πει:
Κάνει ότι κάνει η CASE ή IIF, άρα ποιος ο λόγος ύπαρξης της αφού αυτό που κάνει το κάνουμε ήδη με άλλους τρόπους;
Λογική ερώτηση εφόσον κάποιος δει απομονωμένα την χρήση της. Δυστυχώς, κατά την προσωπική μου άποψη, τα παραδείγματα που υπάρχουν στο documentation της δεν βοηθάνε στην κατανόηση της χρήσης της καθώς εστιάζονται στο βασικό συντακτικό της.
Αλλά για αυτό είμαστε εδώ για να δείξουμε πότε και πως μπορούμε να την εκμεταλλευτούμε, όπως πάντα με παράδειγμα.
NULLIF usage
Use case A
Έχω ένα Customers table που έχει 9Μ πελάτες και όπως συνήθως γίνεται υπάρχει το πεδίο της χώρας που o πελάτης είναι.
Θέλω να μετρήσω τους πελάτες που έχω, εκτός από αυτούς που είναι σε μια συγκεκριμένη χώρα. Αυτό εύκολα κάποιος μπορεί να το κάνει με το παρακάτω query
T-SQL Query
SELECT COUNT(*) AS ExceptGermany
FROM Sales.Customers
WHERE country <>'Germany'
Αν σε αυτό το query θελήσω να έχω και το συνολικό αριθμό των πελατών τότε τα πράγματα αλλάζουν καθώς ή θα πρέπει να κάνω χρήση variables ή να φτιάξω UDF ή να κάνω χρήση subquery όπως παρακάτω:
T-SQL Query
SELECT COUNT(*) AS AllCountries,
(SELECT COUNT(*) FROM Sales.Customers WHERE country <>'Germany') AS ExceptGermany
FROM Sales.Customers
Σε αυτή την περίπτωση έχω ένα query που έχει duration 1387 ms και απασχόλησε την CPU 2766 ms (τα νούμερα είναι από το δικό μου lab) και το execution plan που o SentryOne Plan Explorer μου δείχνει είναι το παρακάτω:
Αν όμως σκεφτώ το πως λειτουργούν τα aggregate functions όπως η COUNT, COUNT_BIG, AVG, MIN, MAX , SUM κ.α όπου αγνοούν τα null τότε η NULLIF είναι αυτή που μου χρειάζεται. Αντί να γράψω το παραπάνω query το γράφω με τον τρόπο παρακάτω:
T-SQL Query
SELECT COUNT(*) AS AllCountries,
COUNT(NULLIF(country,'Germany')) AS ExceptGermany
FROM Sales.Customers
Πλέον έχω ένα query με duration 915 ms, απασχόληση της CPU 1824 ms και το παρακάτω execution plan.
Θεωρώ ότι είναι σαφώς καλύτερα τα πράγματα. Τι λέτε;
Use case B
Η NULLIF είναι ένα expression που μπορεί να συνδυαστεί και σε άλλες περιπτώσεις.
Για παράδειγμα στη παρακάτω χρήση της CASE
T-SQL Query
SELECT CASE WHEN @a=@b THEN NULL ELSE @a END;
Το οποίο μπορεί να γίνει
T-SQL Query
SELECT NULLIF (@a,@b)
Use case C
Aκόμα και σε WHERE όπου ψάχνουμε να βρούμε σε ένα πεδίο τις γραμμές που σε αυτό είναι null αλλά διαπιστώνουμε ότι υπάρχουν και γραμμές με empty string οπότε γράφουμε κάτι σαν αυτό
T-SQL Query
SELECT *
FROM T
WHERE col1 is null OR col1 = '';
Το οποίο με την χρήση της NULLIF μπορεί να γίνει
T-SQL Query
SELECT *
FROM T
WHERE ΝULLIF(col1,'') is null ;
Conclusion
Είδαμε μερικά παραδείγματα για το πως μπορούμε να χρησιμοποιήσουμε τη NULLIF, υπάρχουν πολλά ακόμα. Αυτό που λέω πάντα είναι ότι χρησιμοποιούμε πάντα αυτό που έχει την καλύτερη απόδοση στην εκάστοτε περίπτωση.
//Antonios Chatzipavlis