【问题标题】:How to handle nullable column in table join如何处理表连接中的可为空列
【发布时间】:2013-04-19 13:23:29
【问题描述】:

我有一种情况,我试图查找在某个版本中有效的属性。我在下面有一个版本表和属性表。属性记录有一个版本,它们被引入和删除。

我正在尝试选择在引入和删除之间的属性。但是,删除是空的,这使我的加入变得混乱。我已经用下面的 SQL 进行了补偿(以一种丑陋的方式)。如果删除的 in 为 null,我将其设置为 int 的最大值。这可行,但是当 Removed In 为 null 时忽略连接中的第二个限定条件会很好。有什么想法吗?

**Version**
    id      Name
    ---     -----------------
    1           VersionA
    2           VersionB

**Property**
    id          Name                IntroducedInVersion     RemovedInVersion
    ---         -----------------   -------------------     -----------------
    1               Property1       1                       null
    2               Property2       1                       2


SELECT 
    p.PropertyName
    ,p.IntroducedInVersion
    ,p.RemovedInVersion
FROM
    Version v
    join Property p on p.IntroducedInVersion <= v.Id 
        and ISNULL(cp.RemovedInVersion, 2147483647) > v.Id
WHERE 
    v.Id = 1

【问题讨论】:

    标签: sql sql-server join null


    【解决方案1】:

    你可以这样做:

    SELECT 
      p.PropertyName
      ,p.IntroducedInVersion
      ,p.RemovedInVersion
    FROM Version v
    join Property p
      on (RemovedInVersionp is null
        and v.id > IntroducedInVersion)
        or
        v.id between IntroducedInVersion
             and RemovedInVersion - 1
    WHERE  v.Id = 1
    

    但我认为它的性能不如您原来的查询。

    更好的选择是:

    SELECT 
      p.PropertyName
      ,p.IntroducedInVersion
      ,p.RemovedInVersion
    FROM Version v
    join Property p
      on v.id between IntroducedInVersion
           and ifnull(RemovedInVersion - 1, v.id)
    WHERE v.Id = 1
    

    之所以有效,是因为一个值等于它自己,所以它会“介于”它自己和另一个值之间。

    【讨论】:

    • 感谢@Bohemian,我认为如果我将“ifnull(RemovedInVersion, v.id)”更改为“ifnull(RemovedInVersion - 1, v.id)”,这将起作用。我不希望 RemovedInVersion 具有包容性。
    猜你喜欢
    • 1970-01-01
    • 2013-08-08
    • 2019-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-05
    • 1970-01-01
    相关资源
    最近更新 更多