Какво е NULL? NULL или NULL маркерът е начинът, по който представяме неизвестна стойност в SQL, като SQL имам предвид стандартния език за структурирани заявки, а не MS SQL Server. Последното изречение ни връща малко назад към 1969 г., когато стандартът е дефиниран за първи път от д-р E.F. Codd. NULL става необходимо, защото трябва да мислим от гледна точка на това, което се нарича тризначна предикатна логика. Предикатът е свойството на израз, който или притежава, или не. По номинална стойност човек би си помислил за две възможности:ВЯРНА или НЕПРАВНА. Има обаче и трета възможност:НЕИЗВЕСТНО.
Да вземем пример. Ако приемем, че атрибут (колона) в нашата връзка (Таблица) представлява данъчен идентификационен номер (TIN) на набор от собственици на малък бизнес в Акра, Гана. Колоната за записа на всеки собственик на бизнес ще бъде попълнена с неговия/нейния TIN и можем да използваме тази колона, за да определим някой друг атрибут, като например дали той/тя е актуален в данъчните плащания. Въпреки това, има две допълнителни възможности в този случай на употреба:
- Собственикът на бизнеса има TIN и е актуален.
- Собственикът на бизнеса няма TIN и (очевидно) не е актуален.
Горното описва това, което д-р Код нарече четиризначна предикатна логика. Стандартът SQL обаче опростява тези две допълнителни условия, като го дефинира като неизвестен, т.е. NULL. Не знаем TIN на собственика на бизнеса и не можем да определим друга стойност от атрибута на засегнатия собственик на бизнес. И така, NULL е НЕИЗВЕСТНО и е третата стойност в стандартната тризначна предикатна логика.
NULL е специално
Дефиницията на NULL налага третирането на маркера по различен начин от действителните стойности. Следват примери:
- Няма такова нещо като филтър „WHERE =NULL;“. Правилният израз би бил „WHERE IS NULL;“. Същото важи и за обратния израз.
- Когато сортирате SQL във възходящ ред, можете да изберете да изброите NULL първи или последни. По подразбиране първо се изброяват NULL.
- Не можете да сравнявате NULL стойности. Това трябва да е очевидно, тъй като казахме, че NULL е НЕИЗВЕСТНО.
- Когато опитът за конкатенация включва колона NULL, резултатът е NULL.
Общи функции, свързани с NULL
Следват три често срещани функции, свързани с NULL в SQL Server
ISNULL
ISNULL – Заменя NULL с определена заместваща стойност. Списък 1 и Фиг. 1 показват прости примери за ISNULL.
-- Listing 1: Simple Example of ISSNULL SELECT ISNULL (NULL, 3) NULLREPLACEMENT; SELECT ISNULL (NULL,'GREEN') NULLREPLACEMENT; SELECT ISNULL (NULL,'2018-12-25') NULLREPLACEMENT;
Фигура 1:Прост пример за ISNULL
NULLIF
NULLIF връща NULL е стойността на двата аргумента са равни.
-- Listing 2: Simple Example of NULLIF SELECT NULLIF(3,3) AS NULLIFF; SELECT NULLIF(3,5) AS NULLIFF; SELECT NULLIF('RED','RED') AS NULLIFF; SELECT NULLIF('GREEN','RED') AS NULLIFF;
Фиг. 2:Прост пример за NULLIF
СЛИВАНЕ
COALESCE връща първата стойност, различна от NULL от предоставения списък. Списък 1 показва примери за това, а Фиг. 1 показва изхода от заявките.
-- Listing 3: Simple Example of COALESCE SELECT COALESCE (NULL,'','GREEN','','') AS NULLRESPONSE; SELECT COALESCE (NULL,'GREEN','HOPE','') AS NULLRESPONSE; SELECT COALESCE (1,'','GREEN','','') AS NULLRESPONSE;
Фигура 3:Прост пример за Coalesce
Забележете, че тези прости примери излагат използването на естеството на NULL. NULL и празното пространство НЕ са едно и също. В първия израз COALESCE връща празно пространство, което ни показва, че празно пространство е първата стойност, различна от NULL в списъка.
Разлики между ISNULL и COALESCE
Разликите между ISNULL и COALESCE са били предмет на няколко онлайн статии, както и книги като тези, изброени в раздела за препратки. Тези разлики са обобщени по следния начин:
- ISNULL е собственост на SQL Server, докато COALESCE е стандартна функция за ANSI. Това означава, че за преносимост се предпочита COALESCE.
- ISNULL приема само два аргумента, докато COALESCE може да приеме повече от два аргумента.
- Типът данни на стойността, върната от ISNULL, се определя от типа данни на първия аргумент, докато типът данни на стойността, върната от COALESCE, се определя от типа данни в списъка с най-висок приоритет.
- Когато и двете функции се използват с подзаявки, ISNULL работи по-добре, тъй като COALESCE вътрешно се превежда в CASE израз, което го прави склонен да повтаря сканирания.
Ицик Бен-Ган също изследва други последици от преобразуването на COALESCE в израз на case в своята статия, връзката към която е предоставена в края на тази статия.
Примерни случаи на употреба
Искаме да покажем на уеб портал списъка с клиенти въз основа на определени критерии от таблицата, която създаваме в листинг 4. Задачи 1 и 2 дават възможни изисквания и използваме ISNULL и COALESCE, за да отговорим на изискванията.
--Listing 4: Table Creation Script CREATE TABLE CUSTOMER (ID INT IDENTITY (1,1) ,FIRSTNAME VARCHAR(50) ,LASTNAME VARCHAR(50) ,SEX CHAR(1) ,ADDRESS VARCHAR(300) ,FIRSTTRANDATE DATETIME ,PHONENUMBER1 BIGINT ,PHONENUMBER2 BIGINT ,PHONENUMBER3 BIGINT); GO INSERT INTO CUSTOMER VALUES ('KENNETH','IGIRI','M','ACCRA, GHANA',GETDATE(),'0245335678','0555335678',NULL); INSERT INTO CUSTOMER VALUES ('RICHARD','HANO','M','BUDAPEST, HUNGARY',GETDATE(),'889189400122',NULL,NULL); INSERT INTO CUSTOMER VALUES ('GEORGINA','APPIAH','F','ACCRA, GHANA','09-16-2018','02456665678','0275339678',NULL); INSERT INTO CUSTOMER VALUES ('HOWARD','KLEVIA',NULL,'HAGUE, SWITZERLAND','02-16-2017','3499285782',NULL,NULL); INSERT INTO CUSTOMER VALUES ('ZEN','GREGOR',NULL,'SHANGHAI, CHINA','06-23-2018','0245335678','0555335678',NULL); INSERT INTO CUSTOMER VALUES ('IHEOMA','AWA','F','LAGOS, NIGERIA',GETDATE(),'0245335678','0555335678',NULL);
Фиг. 4 Примерна таблица
Задача 1 :Върнете списъка с всички клиенти, които не са предоставили алтернативен телефонен номер.
--Listing 5: Table List of Customers with no Secondary Phones --A: The Simple Answer SELECT * FROM CUSTOMER WHERE PHONENUMBER2 IS NULL ; --B: Presenting the Result Set Better SELECT FIRSTNAME ,LASTNAME ,ADDRESS ,FIRSTTRANDATE ,PHONENUMBER1 AS [PRIMARY PHONE NUMBER] ,ISNULL(CAST(PHONENUMBER2 AS VARCHAR), 'NO SECONDARY PHONE') AS [SECONDARY PHONE NUMBER] FROM CUSTOMER WHERE PHONENUMBER2 IS NULL ;
Използвайки COALESCE (или ISNULL), можем да представим необходимата информация много по-добре, като използваме текст, който гласи „Без вторичен телефон“.
Фиг. 5 Набор от резултати за листинг 5
Задача 2 :Върнете списъка с всички клиенти, техния основен телефонен номер, и всеки друг алтернативен телефонен номер.
--Listing 6: Table List of Customers with an Other Alternate Number SELECT FIRSTNAME ,LASTNAME ,ADDRESS ,FIRSTTRANDATE ,PHONENUMBER1 AS [PRIMARY PHONE NUMBER] ,COALESCE(CAST(PHONENUMBER2 AS VARCHAR),CAST(PHONENUMBER3 AS VARCHAR), 'NO OTHER PHONE') AS [OTHER PHONE NUMBER] FROM CUSTOMER ;
Фиг. 6 Набор от резултати за листинг 6
В този случай ISNULL не е опция, тъй като предаваме три аргумента.
Заключение
В тази статия обсъдихме концепцията за NULL, тъй като тя се отнася до тризначна предикатна логика и описахме популярни функции, които използваме в SQL Server за работа с набори от данни, съдържащи NULL. Видяхме и примери за това как могат да се използват тези функции. Много други препратки се задълбочават в използването, ползите и ограниченията на тези функции. Горещо препоръчвам книгите и блоговете на Ицик Бен-Ган като добър източник на информация.
Препратки
- NULLIF (Transact-SQL)
- COALESCE (Transact-SQL)
- Статията на Ицик Бен-Ган