Почему count (1 / null) работает, а count (null / null) - нет? - PullRequest
3 голосов
/ 18 октября 2019

Я видел этот пример в презентации в последнее время. При выполнении запроса, подобного следующему:

SELECT COUNT(NULL)

Вы получаете следующую ошибку:

Тип данных операнда NULL недопустим для оператора подсчета.

Когда вы запустите это:

SELECT COUNT(1/NULL)

В результате вы получите 0, хотя само деление в результате даст NULL. То же самое происходит, если вы поменяете 1 и NULL.

Но если вы сделаете это:

SELECT COUNT(NULL/NULL)

Вы снова получите ту же ошибку, что и первый запрос (само деление допустимо, выдает NULL).

Может кто-нибудь объяснить, как работает сервер sql для получения таких результатов?

Ответы [ 3 ]

7 голосов
/ 18 октября 2019

В SQL Server определенные агрегатные функции, такие как COUNT, MIN, MAX и такие функции, как DATEADD, требуют тип данных. NULL, сам по себе, не имеет ни одного, так что это выдает ошибку:

SELECT COUNT(NULL) -- Operand data type NULL is invalid for count operator.

Аналогично для:

SELECT COUNT(NULL/NULL)

Для 1/NULL тип данных INT изначение равно NULL, поэтому это работает:

SELECT COUNT(1/NULL) -- 0

Аналогично для:

SELECT COUNT(CAST(NULL AS INT)) -- 0
1 голос
/ 18 октября 2019

Это на самом деле ошибка компилятора. Когда вы запускаете пакет, T-SQL анализируется, и выдается ошибка в операторах SELECT COUNT(NULL); и SELECT COUNT(NULL/NULL); в это время, а не во время выполнения.

Если вы запустите пакет ниже, вы увидите это довольно быстро:

PRINT 'testing 1'

SELECT COUNT(NULL); --Error at compile
GO

PRINT 'testing 2'

SELECT COUNT(1/NULL); --Runs
GO

PRINT 'testing 3'

SELECT COUNT(NULL/NULL);  --Error at compile
GO

PRINT 'testing 4'

SELECT COUNT(0/0); --Error at run time

Обратите внимание, что операторы testing 1 и testing 3 никогда не появляются.

Значение NULL, onу него нет типа данных. Выражение, в котором все стороны выражения равны NULL, фактически будет иметь неизвестный тип данных.

Если указать тип данных NULL, проблема не возникает. случиться:

PRINT 'testing 5'

SELECT COUNT(CONVERT(int,NULL));
GO

PRINT 'testing 6'
DECLARE @N int;

SELECT COUNT(@N);
0 голосов
/ 18 октября 2019

Проблема связана с типом данных. Если мы выполним следующее, мы увидим, что только NULL не имеет типа данных:

SELECT SQL_VARIANT_PROPERTY(NULL,'BaseType')

Что соответствует ошибке, которую вы видите.

Мы можем заставить NULL иметь выбранный тип данных, используя приведениев этом случае ошибка устраняется:

SELECT COUNT(cast(NULL as int))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...