带有 NULL 列的 SQL 连接

发布于 2024-09-05 13:48:47 字数 1146 浏览 3 评论 0原文

我有以下表格:

表 a

字段类型NullKey
bidint(10) unsignedYES
cidint(10) unsignedYES

表 b

字段类型Null
bidint(10) unsignedNO
cidint(10) unsignedNO
dataint( 10) unsignedNO

当我想从 b 中选择 a 中存在相应 bid/cid 对的所有行时,我只需使用自然连接 SELECT b.* FROM b NATURAL JOIN a; 以及所有内容很好。

a.bida.cidNULL 时,我想获取其他列匹配的每一行,例如 如果a.bidNULL,我想要其中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)

有没有更好的方法呢?

I'm having the following tables:

Table a

FieldTypeNullKey
bidint(10) unsignedYES
cidint(10) unsignedYES

Table b

FieldTypeNull
bidint(10) unsignedNO
cidint(10) unsignedNO
dataint(10) unsignedNO

When I want to select all rows from b where there's a corresponding bid/cid-pair in a, I simply use a natural join SELECT b.* FROM b NATURAL JOIN a; and everything is fine.

When a.bid or a.cid is NULL, I want to get every row where the other column matches, e.g. if a.bid is NULL, I want every row where a.cid = b.cid, if both are NULL I want every column from b.

My naive solution was this:

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)

Is there any better way to to this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

白云悠悠 2024-09-12 13:48:47

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 ) )
                )

The ISNULL function is not actually ANSI compliant. Yes, you do need to check for nulls in both columns. Another way to write your query would be:

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 ) )

Yet another way that avoids the use of 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 ) )
                )
独留℉清风醉 2024-09-12 13:48:47

不,差不多就是这样了。

(为了符合 ANSI SQL FWIW,我通常将 ISNULL(a.bind) 改写为 a.bind IS NULL。)

No, that's pretty much it.

(I'd generally rephrase ISNULL(a.bind) as a.bind IS NULL for ANSI SQL compliance FWIW.)

我是有多爱你 2024-09-12 13:48:47

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

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

Too old, but here is my 2 cents, it might be useful for someone:

ISNULL(a.cid, 0) = ISNULL(b.cid) AND ISNULL(a.bid, 0) = ISNULL(b.bid) 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文