用三元布尔逻辑比较SQL Server中的元组



我有一个关于三元布尔逻辑的问题,它影响如何在我们的LINQ提供程序中实现多态实体之间的比较。

在SQL中,如果使用Country的外键连接Region表:

SELECT * From Region r1, Region r2
WHERE r1.Country == r2.Country 

(注意:无论使用JOIN还是WHERE语法,结果都是相同的)

它将返回条件为真的值,而不是条件为假或未知的值(因为有些键为空)。如果我们否定条件

SELECT * From Region r1, Region r2
WHERE r1.Country != r2.Country 

我们获得条件为真(现在是不同的键)的值,我们将跳过具有相同键的值,或者具有空值的值,因为条件再次返回未知。即使我们这样写:

SELECT * From Region r1, Region r2
WHERE not(r1.Country == r2.Country) 

未知将被传播,因此在这个简单的条件下,null永远不会出现。到目前为止一切顺利。

现在让我们想象一个地区可以有一个国家(对于欧洲小国)或一个州(对于美国,俄罗斯,中国…)。如果区域有一个State,它将有Country null,反之亦然。

我们如何将[Country,State]对连接起来,使其具有与以前相同的属性?:

SELECT * From Region r1, Region r2
WHERE r1.Country == r2.Country OR r1.State == r2.State

此表达式如果连接将返回true,否则返回未知。我们希望它只在所有字段为空的情况下返回未知,否则如果我们取反:

SELECT * From Region r1, Region r2
WHERE not(r1.Country == r2.Country OR r1.State == r2.State)

它不返回行!如果我们尝试一个更复杂的表达式:

SELECT * From Region r1, Region r2
WHERE (r1.Country == r2.Country AND r1.Country IS NOT NULL AND r2.Country IS NOT NULL)  
   OR (r1.State   == r2.State   AND r1.State   IS NOT NULL AND r2.State   IS NOT NULL) 

如果匹配则返回真值,否则返回假值,永远不返回空值。然后,如果我们取负值,它将返回所有行都为空的值,这与第一个示例中的行为不同。

那么哪个表达式比较这对将表现得像SQL相等?

  • 匹配
  • 时为True
  • 当不匹配
  • 时为False
  • 当某些操作数为空时未知。

创建计算列:

Location AS COALESCE(Country, State)

,将其索引并像往常一样进行比较:

SELECT  *
FROM    Region r1
JOIN    Region r2
ON      r2.Location = r1.Location

如果CountryState都是NULL,则LocationNULL

更新:

如果CountryState可以相互比较,则创建一个额外的列,显示使用哪一个:

LocationType AS CASE WHEN Country IS NOT NULL THEN 1 WHEN State IS NOT NULL THEN 2 END,
LocationId AS COALESCE(Country, State)

,索引两个并使用它们进行比较:

SELECT  *
FROM    Region r1
JOIN    Region r2
ON      r2.LocationType = r1.LocationType
        AND r2.LocationID = r1.LocationID

你可以试试这个吗:

SELECT *
FROM Region r1
  JOIN Region r2
    ON ( r1.Country = r2.Country 
         AND r1.State IS NULL 
         AND r2.State IS NULL
       )
    OR ( r1.State = r2.State 
         AND r1.Country IS NULL 
         AND r2.Country IS NULL
       )

相关内容

  • 没有找到相关文章

最新更新