SQL 空值内连接

发布于 2024-08-20 15:31:45 字数 241 浏览 5 评论 0原文

SELECT * FROM Y
INNER JOIN X ON ISNULL(X.QID, 0) = ISNULL(y.QID, 0) 

在像这样的连接中有一个连接 Isnull 使它变慢。这就像有一个条件连接。 对于这样的事情有什么解决办法吗? 我有很多 QID 为 Null 的记录

任何人都可以找到不需要修改数据的解决方法

I have a Join

SELECT * FROM Y
INNER JOIN X ON ISNULL(X.QID, 0) = ISNULL(y.QID, 0) 

Isnull in a Join like this makes it slow. It's like having a conditional Join.
Is there any work around to something like this?
I have a lot of records where QID is Null

Anyone have a work around that doesn't entail modifying the data

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

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

发布评论

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

评论(8

陪我终i 2024-08-27 15:31:45

您有两个选择

INNER JOIN x
   ON x.qid = y.qid OR (x.qid IS NULL AND y.qid IS NULL)

或更简单的选择

INNER JOIN x
  ON x.qid IS NOT DISTINCT FROM y.qid

You have two options

INNER JOIN x
   ON x.qid = y.qid OR (x.qid IS NULL AND y.qid IS NULL)

or easier

INNER JOIN x
  ON x.qid IS NOT DISTINCT FROM y.qid
记忆で 2024-08-27 15:31:45

如果您希望从 Y.QID 中包含空值,那么最快的方法是

SELECT * FROM Y
左连接 X ON y.QID = X.QID

注意:仅当您需要左表中的空值(即 Y)(在上述情况下)时,此解决方案才适用。

否则
<代码>
x.qid 上的内连接 x 与 y.qid 不同

是正确的做法

If you want null values to be included from Y.QID then Fastest way is

SELECT * FROM Y
LEFT JOIN X ON y.QID = X.QID

Note: this solution is applicable only if you need null values from Left table i.e. Y (in above case).

Otherwise

INNER JOIN x ON x.qid IS NOT DISTINCT FROM y.qid

is right way to do

旧情别恋 2024-08-27 15:31:45

这篇文章对这个问题进行了很好的讨论。你可以使用

SELECT * 
FROM Y
INNER JOIN X ON EXISTS(SELECT X.QID 
                       INTERSECT 
                       SELECT y.QID);

This article has a good discussion on this issue. You can use

SELECT * 
FROM Y
INNER JOIN X ON EXISTS(SELECT X.QID 
                       INTERSECT 
                       SELECT y.QID);
殤城〤 2024-08-27 15:31:45

您是否致力于使用内连接语法?

如果没有,您可以使用以下替代语法:

SELECT * 
FROM Y,X
WHERE (X.QID=Y.QID) or (X.QUID is null and Y.QUID is null)

Are you committed to using the Inner join syntax?

If not you could use this alternative syntax:

SELECT * 
FROM Y,X
WHERE (X.QID=Y.QID) or (X.QUID is null and Y.QUID is null)
如痴如狂 2024-08-27 15:31:45

我很确定连接甚至没有达到您想要的效果。如果表 a 中有 100 条记录的 qid 为空,表 b 中有 100 条记录的 qid 为空,则所编写的联接应进行交叉联接,并为这些记录提供 10,000 个结果。如果您查看以下代码并运行示例,我认为最后一个可能更符合您想要的结果集:

create table #test1 (id int identity, qid int)
create table #test2 (id int identity, qid int)

Insert #test1 (qid)
select null
union all
select null
union all
select 1
union all
select 2
union all
select null

Insert #test2 (qid)
select null
union all
select null
union all
select 1
union all
select 3
union all
select null


select * from #test2 t2
join #test1 t1 on t2.qid = t1.qid

select * from #test2 t2
join #test1 t1 on isnull(t2.qid, 0) = isnull(t1.qid, 0)


select * from #test2 t2
join #test1 t1 on 
 t1.qid = t2.qid OR ( t1.qid IS NULL AND t2.qid IS NULL )


select t2.id, t2.qid, t1.id, t1.qid from #test2 t2
join #test1 t1 on t2.qid = t1.qid
union all
select null, null,id, qid from #test1 where qid is null
union all
select id, qid, null, null from #test2  where qid is null

I'm pretty sure that the join doesn't even do what you want. If there are 100 records in table a with a null qid and 100 records in table b with a null qid, then the join as written should make a cross join and give 10,000 results for those records. If you look at the following code and run the examples, I think that the last one is probably more the result set you intended:

create table #test1 (id int identity, qid int)
create table #test2 (id int identity, qid int)

Insert #test1 (qid)
select null
union all
select null
union all
select 1
union all
select 2
union all
select null

Insert #test2 (qid)
select null
union all
select null
union all
select 1
union all
select 3
union all
select null


select * from #test2 t2
join #test1 t1 on t2.qid = t1.qid

select * from #test2 t2
join #test1 t1 on isnull(t2.qid, 0) = isnull(t1.qid, 0)


select * from #test2 t2
join #test1 t1 on 
 t1.qid = t2.qid OR ( t1.qid IS NULL AND t2.qid IS NULL )


select t2.id, t2.qid, t1.id, t1.qid from #test2 t2
join #test1 t1 on t2.qid = t1.qid
union all
select null, null,id, qid from #test1 where qid is null
union all
select id, qid, null, null from #test2  where qid is null
寂寞花火° 2024-08-27 15:31:45

嘿,回答这个问题有点晚了,但我也遇到了同样的问题,我意识到你的第二个表中必须有一条 ID 为 0 的记录才能做到这一点:

SELECT * FROM Y
INNER JOIN X ON ISNULL(Y.QID, 0) = ISNULL(X.QID, 0)

要发生,它实际上是说如果没有,则使用0但是如果 Y没有有 ID 为 0 的记录怎么办?

所以,我找到了这个方法(并且适用于我的案例):

SELECT 
  ISNULL(Y.QName, 'ThereIsNone') AS YTableQName
FROM
  X
LEFT OUTER JOIN Y ON X.QID = Y.QID

我的案例的快照

这样,您不需要在第二个表中需要 ID 值为 0 的记录(在本例中为 Y,而 Customers 在我的例子中),或者任何记录

更新

您还可以查看这篇文章以便更好地理解。

Hey it is kind of late to answer that but I got the same question, what I realized is that you must have a record with the ID of 0 in you second table to make this :

SELECT * FROM Y
INNER JOIN X ON ISNULL(Y.QID, 0) = ISNULL(X.QID, 0)

to happen, it actually says if there is none, then use 0. BUT what if Y table does NOT have a record with the ID of 0?

So, I found this method, (and worked for my case):

SELECT 
  ISNULL(Y.QName, 'ThereIsNone') AS YTableQName
FROM
  X
LEFT OUTER JOIN Y ON X.QID = Y.QID

A snapshot of my case

This way you DON'T need a record with 0 ID value in your second table (which is Y in this case and Customers in my case), OR any record at all

UPDATE:

You can also take a look at this post for better understanding.

一抹微笑 2024-08-27 15:31:45

基本上,您想要将两个表连接在一起,其中它们的 QID 列都为空,对吗?但是,您没有强制执行任何其他条件,例如两个 QID 值(这对我来说似乎很奇怪,但没关系)。像下面这样简单的东西(在 MySQL 中测试)似乎可以满足您的要求:

SELECT * FROM `Y` INNER JOIN `X` ON (`Y`.`QID` IS NOT NULL AND `X`.`QID` IS NOT NULL);

这使您可以将 Y 中的每个非空行连接到 X 中的每个非空行。

更新: Rico 说他还想要具有 NULL 值的行,为什么不只是:

SELECT * FROM `Y` INNER JOIN `X`;

Basically you want to join two tables together where their QID columns are both not null, correct? However, you aren't enforcing any other conditions, such as that the two QID values (which seems strange to me, but ok). Something as simple as the following (tested in MySQL) seems to do what you want:

SELECT * FROM `Y` INNER JOIN `X` ON (`Y`.`QID` IS NOT NULL AND `X`.`QID` IS NOT NULL);

This gives you every non-null row in Y joined to every non-null row in X.

Update: Rico says he also wants the rows with NULL values, why not just:

SELECT * FROM `Y` INNER JOIN `X`;
放赐 2024-08-27 15:31:45

您还可以使用 coalesce 函数。我在 PostgreSQL 中对此进行了测试,但它也应该适用于 < a href="http://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#function_coalesce" rel="nofollow">MySQL 或 MS SQL 服务器

INNER JOIN x ON coalesce(x.qid, -1) = coalesce(y.qid, -1)

在评估之前,这会将 NULL 替换为 -1。因此,qid 中一定不能有 -1

You could also use the coalesce function. I tested this in PostgreSQL, but it should also work for MySQL or MS SQL server.

INNER JOIN x ON coalesce(x.qid, -1) = coalesce(y.qid, -1)

This will replace NULL with -1 before evaluating it. Hence there must be no -1 in qid.

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