SQL-Join with NULL-columns

时间:2010-06-12 11:24:07

标签: sql join null

我有以下表格:

Table a
+-------+------------------+------+-----+
| Field | Type             | Null | Key |
+-------+------------------+------+-----+
| bid   | int(10) unsigned | YES  |     |
| cid   | int(10) unsigned | YES  |     |
+-------+------------------+------+-----+
Table b
+-------+------------------+------+
| Field | Type             | Null |
+-------+------------------+------+
| bid   | int(10) unsigned | NO   |
| cid   | int(10) unsigned | NO   |
| data  | int(10) unsigned | NO   |
+-------+------------------+------+

当我想从b中选择a中有相应出价/ cid对的所有行时,我只需使用自然连接SELECT b.* FROM b NATURAL JOIN a;,一切都很好。

当a.bid或a.cid为NULL时,我希望得到另一列匹配的每一行,例如如果a.bid是NULL,我想要a.cid=b.cid的每一行,如果两者都是NULL我想要b中的每一列。

我天真的解决方案是:

SELECT DISTINCT b.* FROM b JOIN a ON ( ISNULL(a.bid) OR a.bid=b.bid ) AND (ISNULL(a.cid) OR a.cid=b.cid )

还有更好的方法吗?

3 个答案:

答案 0 :(得分:8)

ISNULL功能实际上不符合ANSI标准。是的,您需要检查两列中的空值。编写查询的另一种方法是:

Select Distinct b.*
From b
    Join a
        On ( a.bid = b.bid Or ( a.bid Is Null And b.bid Is Null ) )
            And ( a.cid = b.cid Or ( a.cid Is Null And b.cid Is Null ) )

另一种避免使用Distinct的方法:

Select b.*
From b
Where Exists    (
                Select 1
                From a
                Where  ( a.bid = b.bid Or ( a.bid Is Null And b.bid Is Null ) )
                    And ( a.cid = b.cid Or ( a.cid Is Null And b.cid Is Null ) )
                )

答案 1 :(得分:2)

不,这就是它。

(对于ANSI SQL合规性FWIW,我通常将ISNULL(a.bind)改为a.bind IS NULL。)

答案 2 :(得分:1)

太旧了,但这是我的2美分,对某人可能有用

ISNULL(a.cid,0)= ISNULL(b.cid)和ISNULL(a.bid,0)= ISNULL(b.bid)