Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/76.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 两个值怎么可能相等,但又不相等?_Sql_Sql Server_Tsql - Fatal编程技术网

Sql 两个值怎么可能相等,但又不相等?

Sql 两个值怎么可能相等,但又不相等?,sql,sql-server,tsql,Sql,Sql Server,Tsql,当我运行以下查询时: DECLARE @val VARCHAR(10) = 'not null' , @val2 VARCHAR(10) = NULL -- Test 1. IF @val <> @val2 SELECT 'Test 1. They are not equal' -- Are they equal? ELSE SELECT 'Test 1. They are equal' -- Test 2. IF @val = @val2 SELECT 'Te

当我运行以下查询时:

DECLARE 
    @val VARCHAR(10) = 'not null'
    , @val2 VARCHAR(10) = NULL

-- Test 1.
IF @val <> @val2 SELECT 'Test 1. They are not equal' -- Are they equal?
ELSE SELECT 'Test 1. They are equal'

-- Test 2.
IF @val = @val2 SELECT 'Test 2. They are equal' -- Are they not equal
ELSE SELECT 'Test 2. They are not equal'

有人能解释一下这些结果吗?

这是因为SQL中的三值逻辑。任何与空值的比较都会求值为未知值,如果这样说的话,这可以被认为是不正确的,非常明显

请参阅此

它工作正常。 在第一种情况下,如果@val=@val2,则应打印相同的内容,而不是不相同的内容。 您应该在if条件声明后添加开始和结束块。 只要看看下面的脚本就可以了

    DECLARE 
    @val VARCHAR(10) = 'not null'
    , @val2 VARCHAR(10) = NULL

     IF @val = @val2 
     begin
       SELECT 'the same' -- Is it equal?
     end 
     ELSE 
      begin
         SELECT 'not the same'
     end 
     IF @val <> @val2 
     begin 
       SELECT 'the same' -- Is it not equal?
    end
    ELSE 
    begin 
       SELECT 'not the same'
    end 

任何与NULL的比较都不会是真的

因此,该代码只能返回ELSE值

对于SQL中NULL的含义,通常存在误解

乍一看,我们假设NULL表示空。 然后很奇怪,空不等于空,也和空没有什么不同

但是当NULL被理解为未知时,更容易理解。 因为两个未知数不一定是相同的。 也不能说两个未知数是不同的。 即使是已知的也可能与未知不同,但也可能是相同的。 逻辑就是不知道。。。因此无效

但眼见为实,让我们通过一些例子来说明这一点。 下面是一个简单的SQL代码片段,展示了比较是如何处理空值的

-- Sample data
DECLARE @Table TABLE
(
  Id INT IDENTITY PRIMARY KEY,
  Col1 VARCHAR(42),
  Col2 VARCHAR(42)
);

INSERT INTO @Table 
(Col1, Col2) VALUES
('something', NULL),
(NULL, '>4&×'),
(NULL, NULL),
('same', 'same'),
('same is not', 'different is');

SELECT t.*
, CAST(IIF(col1 = col2, 1, 0) AS BIT) AS IsEqual
, CAST(IIF(col1 <> col2, 1, 0) AS BIT) AS IsNotEqual
, CAST(IIF(col1 = col2 OR (col1 IS NULL AND col2 IS NULL), 1, 0) AS BIT) AS IsNotDistinctFrom
, CAST(IIF(col1 != col2 OR (col1 IS NOT NULL AND col2 IS NULL) OR (col1 IS NULL AND col2 IS NOT NULL), 1, 0) AS BIT) AS IsDistinctFrom
, CAST(IIF(col1 > col2, 1, 0) AS BIT) AS IsGreaterThen
FROM @Table t
ORDER BY Id;
返回:

Jup,NULL将是NULL

对dbfiddle的测试

关于IsNotDistinctFrom和IsDistinctFrom列? 我只包含了它们,因为在标准SQL中也存在一个空感知比较。
关于这一点的更多细节

空=或比较永远都不是真的。也就是说,在这两种情况下都会得到else值。val VARCHAR10='not null'是一个字符串,val2 VARCHAR10=null是存储在val2中的垃圾值。任何与null的比较都是false,因此在这两种比较中都会使用else分支。@Alejandro,not false,unknown。@Alejandro但not null=null也不是true,所以false在技术上是不正确的。您忘记了选项集ansi_null。如果运行集ansi_为空,则结果将是下一个:相同,相同。当然,如果我们谈论的是SQL Server。虽然对于未知的SQL Server是正确的,但我强烈反对将其称为错误。因为在三值逻辑中,“未知”与“假”有很大不同。正如你的链接所论证的那样。第六章在链接中我会说未知,这可以被认为是不真实的。@DKramer虽然你是对的,但我刚才提到了解释的方式。这篇文章是为了澄清这一点:@DanGuzman Acutally我在想:更正,谢谢。非常感谢您的精彩解释。我完全忘记了IS NOT NULL和IS NULL。谢谢你的支持:好吧,一旦你得到它,它真的很简单。如果要与空字符串进行比较,则可以使varchar不可为null,并插入空字符串。虽然这个答案不太正确,但我非常感谢您花时间帮助我。非常感谢你。幸运的是,LukStorms彻底解决了这个问题。请查看他们的答案,以获得对解决方案的精彩解释。
-- Sample data
DECLARE @Table TABLE
(
  Id INT IDENTITY PRIMARY KEY,
  Col1 VARCHAR(42),
  Col2 VARCHAR(42)
);

INSERT INTO @Table 
(Col1, Col2) VALUES
('something', NULL),
(NULL, '>4&×'),
(NULL, NULL),
('same', 'same'),
('same is not', 'different is');

SELECT t.*
, CAST(IIF(col1 = col2, 1, 0) AS BIT) AS IsEqual
, CAST(IIF(col1 <> col2, 1, 0) AS BIT) AS IsNotEqual
, CAST(IIF(col1 = col2 OR (col1 IS NULL AND col2 IS NULL), 1, 0) AS BIT) AS IsNotDistinctFrom
, CAST(IIF(col1 != col2 OR (col1 IS NOT NULL AND col2 IS NULL) OR (col1 IS NULL AND col2 IS NOT NULL), 1, 0) AS BIT) AS IsDistinctFrom
, CAST(IIF(col1 > col2, 1, 0) AS BIT) AS IsGreaterThen
FROM @Table t
ORDER BY Id;
Id | Col1 | Col2 | IsEqual | IsNotEqual | IsNotDistinctFrom | IsDistinctFrom | IsGreaterThen -: | :---------- | :----------- | :------ | :--------- | :---------------- | :------------- | :------------ 1 | something | null | False | False | False | True | False 2 | null | >4&× | False | False | False | True | False 3 | null | null | False | False | True | False | False 4 | same | same | True | False | True | False | False 5 | same is not | different is | False | True | False | True | True