【问题标题】:SQL join by 2 values, one of them can be nullSQL join 2个值,其中一个可以为null
【发布时间】:2019-06-05 14:13:22
【问题描述】:

我有两张桌子

+------------+-----------+-----------+
| itemid     | version   | anything  |
+------------+-----------+-----------+
| foo        | v0        |  blah     |
| foo        | v1        |  blah     |
| foo        | NULL      |  blah     |
| foo        | v2        |  meh      |
| bar        | v0        |  meh      |
| bar        | v1        |  24       |
| baz        | NULL      |  25       |
| qux        | NULL      |  26       |
+------------+-----------+-----------+

+------------+-----------+-----------+
| itemid     | version   | something |
+------------+-----------+-----------+
| foo        | v0        |  weck     |
| foo        | NULL      |  wock     |
| foo        | v2        |  weck     |
| bar        | v0        |  meck     |
| bar        | v1        |  cuack    |
| baz        | NULL      |  crack    |
| qux        | NULL      |  blah     |
+------------+-----------+-----------+

我需要通过itemidversion 加入这两个表,所以结果如下:

+------------+-----------+-----------+-----------+
| itemid     | version   | anything  | something |
+------------+-----------+-----------+-----------+
| foo        | v0        |  blah     |  weck     |
| foo        | v1        |  blah     |  NULL     |
| foo        | NULL      |  blah     |  wock     |
| foo        | v2        |  meh      |  weck     |
| bar        | v0        |  meh      |  meck     |
| bar        | v1        |  24       |  cuack    |
| baz        | NULL      |  25       |  crack    |
| qux        | NULL      |  26       |  blah     |
+------------+-----------+-----------+-----------+

我在做

SELECT t1.itemid,
       t1.version,
       t1.anything,
       t2.something
FROM table1 AS t1
LEFT JOIN table2 AS t2
ON t1.itemid=t2itemid AND t1.version=t2.version

它适用于具有版本值的行,但如果版本值为NULL,则具有空值的行如下所示:

+------------+-----------+-----------+-----------+
| itemid     | version   | anything  | something |
+------------+-----------+-----------+-----------+
| foo        | NULL      |  blah     |  NULL     |
| baz        | NULL      |  25       |  NULL     |
| qux        | NULL      |  26       |  NULL     |
+------------+-----------+-----------+-----------+

我尝试使用以下方法更改连接条件:

ON t1.itemid=t2.itemid AND (t1.version=t2.version OR ((t1.version is null) AND (t2.version is null)))

结果一模一样

我也试过改变条件:

ON t1.itemid=t2.itemid AND (t1.version=t2.version OR ((isnull(t1.version,'-')) AND (isnull(t1.version,'-'))))

然后我得到错误:An expression of non-boolean type specified in a context where a condition is expected,near 'AND' [SQL State=S0001, DB Errorcode=4145]

如何加入具有相同 itemid 和 NULL version 的行??

编辑:也许这并不重要,但在我的真实查询中,table1 和 table2 是选择结果,对于同样包含 itemid 和版本的示例,我还跳过了第三个选择。所以这是一个选择的连接。

【问题讨论】:

  • 用您正在使用的数据库标记您的问题。您的第一个版本应该可以工作。你确定NULLNULL 而不是"NULL",一个字符串?
  • 您是否尝试过根据您的情况合并版本?您应该能够将空值替换为类似 v99999 之类的东西,您可能永远不会真正拥有,但由于它是一个实际值,因此它适用于相等性检查。
  • ON t1.itemid=t2itemid 你有一个错字 - 错过了点。 ON t1.itemid=t2.itemid
  • 我刚刚尝试过coalesce(t1.version,'999')=coalesce(t2.version,'999'),但结果相同
  • @GeorgeGarchagudashvili ys,这是我在编写示例时犯的错字,在原始代码中是可以的。如果错了我会直接报错

标签: sql join null


【解决方案1】:

在您的上一个示例中,您错误地使用了 ISNULL - 尝试 -

   SELECT t1.itemid,
           t1.version,
           t1.anything,
           t2.something
    FROM table1 AS t1
    LEFT JOIN table2 AS t2
    ON t1.itemid=t2itemid AND ISNULL(t1.version, '-') = ISNULL(t2.version, '-')

【讨论】:

  • 你说得对,我改变了它,但我仍然无法在空值的结果中得到 t1.anything 和 t2.something
【解决方案2】:

我终于找到了问题所在。似乎 NULL 字段并不总是NULL,有时NULL 字段包含不是NULL''' ' 的东西

我不知道这个字段究竟包含什么,是一个不可见的字符。不过好在version字段总是以V开头,所以我把这个语句放在了version字段中:

IIF (t1.version like 'V%', t1.version, NULL)

这样我保证这个字段包含一个NULL 值,然后一切似乎都可以正常工作。

如果不是 'V%',这些值应该始终为 NULL,所以可能是由谁在 db 中引入这些行引起的...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-08-25
    • 1970-01-01
    • 2013-05-13
    • 1970-01-01
    • 2019-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多