Pull to refresh

Переход через NULL

Reading time2 min
Views11K
Многие знают и используют встроенную функцию ISNULL(X, Y), которая заменяет первый аргумент на второй в случае, если он (первый) NULL. Менее употребима обратная встроенная функция NULLIF(X, Y), которая возвращает NULL, если первый аргумент равен второму. Комбинация этих двух функций позволяет избежать использования конструкций IF-ELSE или CASE-WHEN, что делает код компактнее. Если интересно посмотреть пару примеров — добро пожаловать под кат.

Например, вот код, который выводит 10 случайных целых чисел в диапазоне от 1 до 37, и ближайшее большее или равное выведенному числу значение, кратное 6.

SELECT
	Q.Src,
	CASE 
          WHEN Q.Src % 6 = 0 THEN Q.Src 
          ELSE Q.Src + (6 - Q.Src % 6) 
        END AS NextTimes6
FROM (
	SELECT TOP 10 
		CONVERT(INT, 1 + 37 * RAND(CHECKSUM(NEWID()))) Src
	FROM SYSOBJECTS S
) Q

От CASE..WHEN можно избавиться, проделав следующий трюк — обратив в NULL результат выражения Q.Src % 6 в случае, если остаток равен 0, зная, что результат любой операции с NULL равен NULL, и восстанавливая затем обратно NULL до 0 внешней функцией ISNULL:

SELECT
	Q.Src,
	Q.Src + ISNULL(6 - NULLIF(Q.Src % 6, 0), 0) AS NextTimes6
FROM (
	SELECT TOP 10 
		CONVERT(INT, 1 + 37 * RAND(CHECKSUM(NEWID()))) Src
	FROM SYSOBJECTS S
) Q

Еще один пример — разделение строки на две части по пробелу (например, имени из строки Имя<пробел>Фамилия. Типичная проблема здесь при решении «в лоб» — падение функции LEFT при передаче ей аргумента -1 в качестве значения количества отрезаемых символов в случае, когда пробела в исходной строке не находится (CHARINDEX возвращает 0):

SELECT
	Q.Src,
	CASE
	  WHEN CHARINDEX(' ', Q.Src) > 0 THEN LEFT(Q.Src, CHARINDEX(' ', Q.Src) - 1)
	  ELSE Q.Src
    END AS NameOnly
FROM (
	SELECT N'Петр Иванов' AS Src
	UNION ALL
	SELECT N'Иван'
) Q

Превращается в:

SELECT
	Q.Src,
	LEFT(Q.Src, ISNULL(NULLIF(CHARINDEX(' ', Q.Src), 0) - 1, LEN(Q.Src))) AS NameOnly
FROM (
	SELECT N'Петр Иванов' AS Src
	UNION ALL
	SELECT N'Иван'
) Q

Приятного SQL-программирования!
Tags:
Hubs:
+4
Comments16

Articles