Где мой банан? (Проблема с SQL Query NULL)

У меня есть эта таблица:

CREATE TABLE [dbo].[Fruit](
    [RecId] [int] IDENTITY(1,1) NOT NULL,
    [Banana] [int] NULL,
    [TextValue] [varchar](50) NULL
)

И следующий фрагмент кода:

DECLARE @FruitInput INT = NULL
SELECT * FROM Fruit WHERE Banana = @FruitInput 

Эта запись находится в этой таблице:

1|NULL|Hello 

Почему мой запрос не возвращает эту запись?

Ответ 1

Это потому, что Null is undefined. Null ни равный, ни равный ни с чем. Подробнее читайте в MSDN.

Нулевые значения можно проверить с помощью функций is null (или is not null) или isnull() или coalesce() в зависимости от требования.

Попробуйте следующее:

SELECT * FROM Fruit WHERE Banana is null

И следующий запрос для выбора all the records в случае, если @FruitInput is null:

SELECT * FROM Fruit WHERE @FruitInput is null or Banana = @FruitInput

Ответ 2

NULL не равен NULL, используйте NULL для проверки нулевой строки:

SELECT * FROM Fruit WHERE Banana IS NULL

В этом случае, поскольку у вас есть NULL в переменной, вы можете использовать оператор ISNULL:

SELECT * FROM Fruit WHERE ISNULL(Banana, 0) = ISNULL(@FruitInput, 0)

Это гарантирует, что вы можете проверить любое значение NULL или иначе сравнить 0 с 0 - очевидно, если у вас есть строки, где банана NULL и @FruitInput равно 0, это будет соответствовать им, при необходимости скорректируйте

(например, вы можете использовать -1 или строку)

SELECT * FROM Fruit WHERE ISNULL(Banana, '') = ISNULL(@FruitInput, '')

Изменить: Нет, вы не можете, потому что по какой-то причине 0 = '' в SQL...?!

Я полагаю, что способ сделать это (возможно, это не так, я не проверял план):

select * from Fruit 
where 1 = CASE
    WHEN @FruitInput IS NULL AND banana IS NULL THEN 1
    WHEN @FruitInput = banana THEN 1 
    ELSE 0
END

Ответ 3

Значение NULL указывает, что значение неизвестно. Значение NULL отличается от пустого или нулевого значения. Нет двух нулевых значений. Сравнение двух нулевых значений или между NULL и любым другим значением возвращается неизвестно, поскольку значение каждого NULL неизвестно. Здесь

SELECT * FROM Fruit WHERE Banana IS Null

Ответ 4

Значение NULL означает, что значение данных для столбца неизвестно или недоступно, а сравнение, в котором одно или несколько выражений равно NULL, дает неизвестность, поэтому вы не можете напрямую сравнивать Банану с нулем, но вы должны использовать что-то вроде этого:

SELECT * FROM Fruit
WHERE Banana = @FruitInput OR COALESCE(Banana, @FruitInput) IS NULL

Coalesce вернет первое ненулевое значение, которое он обнаружил, или null, если все значения равны нулю. Предыдущий запрос вернет все строки, где Banana = @FruitInput, если они оба не являются Null, или где они оба являются Null, что эквивалентно этому:

SELECT * FROM Fruit
WHERE (Banana = @FruitInput) OR (Banana IS NULL AND @FruitInput IS NULL)

Вы также можете использовать расширение, которое позволяет сравнивать с нулевыми значениями:

SET ANSI_NULLS OFF;
SELECT * FROM Fruit WHERE Banana = NULL;

но лучше избегать использования этой функции в новых разработках, поскольку в будущих версиях SQL Server ANSI_NULLS всегда будет включен, а изменение его значения приведет к ошибке.