Mysql 如何从表A中获取在表B中没有条目的条目?(SQL)
在mysql中,我有Mysql 如何从表A中获取在表B中没有条目的条目?(SQL),mysql,sql,Mysql,Sql,在mysql中,我有tableA和valueA行和tableB行和userid行和valueB 现在我想要tableA中的所有条目,它们在tableB中没有具有相同userid的条目 我尝试了几件事,但都不知道我做错了什么 SELECT * FROM `tableA` left join `tableB` on `tableA`.`userid` = `tableB`.`userid` 这实际上是一个很好的开始。它为我提供了表格A+中的所有条目以及表格B中的相应值。如果它们不存在,则显示为NU
tableA
和valueA
行和tableB
行和userid
行和valueB
现在我想要tableA
中的所有条目,它们在tableB
中没有具有相同userid
的条目
我尝试了几件事,但都不知道我做错了什么
SELECT * FROM `tableA`
left join `tableB` on `tableA`.`userid` = `tableB`.`userid`
这实际上是一个很好的开始。它为我提供了表格A
+中的所有条目以及表格B
中的相应值。如果它们不存在,则显示为NULL
(在phpmyadmin中)
太糟糕了,结果是空的。也许这太容易了。(顺便说一句:tableA
有~10k个条目,tableB
有~7k个条目,userid
在每个条目中都是唯一的。如果它能做到我希望它做的事情,结果决不会是空的)
这也不起作用,老实说,这看起来完全是自相矛盾的。不管怎么说,我现在不知所措。为什么我的第二个查询不起作用?什么是正确的解决方案?更改代码上的
=NULL
for为NULL
。您也可以使用不存在
:
SELECT *
FROM `tableA` A
WHERE NOT EXISTS (SELECT 1 FROM `tableB`
WHERE `userid` = A.`userid`)
更改
=NULL
的在代码上为NULL
。您也可以使用不存在
:
SELECT *
FROM `tableA` A
WHERE NOT EXISTS (SELECT 1 FROM `tableB`
WHERE `userid` = A.`userid`)
你就快到了。第二个问题非常接近!它所需要的只是一个小小的调整: 谓词中需要一个“
为NULL
”而不是“=NULL
”
SELECT * FROM `tableA`
left join `tableB` on `tableA`.`userid` = `tableB`.`userid`
where `tableB`.`valueB` IS NULL
^^
请注意,当比较的一侧(或两侧)为NULL时,相等比较运算符=
将返回NULL(而不是TRUE或FALSE)。(就关系数据库和SQL而言,布尔逻辑有三个值,而不是两个:TRUE、FALSE和NULL。)
顺便说一句。。。查询中的模式(外部联接表上的NULL测试的外部联接)通常称为“反联接”模式。通常的模式是测试连接条件中引用的同一列(或多个列),或具有NOTNULL约束的列,以避免产生不明确的结果。(例如,如果'ValueB'可以有一个空值,并且我们确实匹配了一行,那该怎么办呢?这一点都没有错,只是取决于您是否希望返回该行。)
如果要查找表a中没有匹配行的行,我们通常会这样做:
SELECT * FROM `tableA`
left join `tableB` on `tableA`.`userid` = `tableB`.`userid`
where `tableB`.`userid` IS NULL
^^^^^^ ^^
请注意,IS NULL测试位于
userid
列上,如果找到匹配的行,则该列保证为“notnull”。(如果列为NULL,则该行不会满足连接谓词中的相等性测试。您就快到了。第二个查询非常接近!只需稍微调整一下即可:
SELECT * FROM `tableA`
left join `tableB` on `tableA`.`userid` = `tableB`.`userid`
where `tableB`.`valueB` IS NULL
^^
谓词中需要一个“为NULL
”而不是“=NULL
”
SELECT * FROM `tableA`
left join `tableB` on `tableA`.`userid` = `tableB`.`userid`
where `tableB`.`valueB` IS NULL
^^
请注意,当比较的一侧(或两侧)为NULL时,相等比较运算符=
将返回NULL(而不是TRUE或FALSE)。(对于关系数据库和SQL,布尔逻辑有三个值,而不是两个值:TRUE、FALSE和NULL。)
顺便说一句,查询中的模式(外部联接表上的NULL测试的外部联接)通常被称为“反联接”模式。通常的模式是测试连接条件中引用的同一列(或多个列),或具有NOTNULL约束的列,以避免产生不明确的结果。(例如,如果'ValueB'可以有一个空值,并且我们确实匹配了一行,那该怎么办呢?这一点都没有错,只是取决于您是否希望返回该行。)
如果要查找表a中没有匹配行的行,我们通常会这样做:
SELECT * FROM `tableA`
left join `tableB` on `tableA`.`userid` = `tableB`.`userid`
where `tableB`.`userid` IS NULL
^^^^^^ ^^
请注意,IS NULL测试位于
userid
列上,如果找到匹配的行,则该列保证为“notnull”。(如果列为NULL,则该行不会满足连接谓词中的相等性测试。这将有助于解释使用NULL值的用法:
SELECT * FROM `tableA`
left join `tableB` on `tableA`.`userid` = `tableB`.`userid`
where `tableB`.`valueB` IS NULL
^^
这将有助于解释使用空值的用法:
较便宜的查询是,如果数据库太大,则建议的所有其他查询都太贵:
SELECT * FROM tableA a
WHERE a.userid NOT IN
(SELECT b.user_id FROM tableB b);
成本较低的查询是,如果数据库太大,则建议的所有其他查询的成本都太高:
SELECT * FROM tableA a
WHERE a.userid NOT IN
(SELECT b.user_id FROM tableB b);
尝试<代码>“TabLeb”。“ValueBB是null < /COD>之前也有这个问题。您的第二个查询是如此之近。只需将<代码> = NULL//COD> > <代码>为null 。考虑在UPERID列上进行该测试,如果ValueB列可以包含NULL(如果您真正想要的是B中没有匹配行的行)。请参阅我的答案。尝试<代码>“Table”,“ValueB”是NUL/<代码>也有这个问题。您的第二个查询是如此之近。只需更改<代码> = NULL> /COD> > NUL> <代码>。如果ValueB列可以包含NULL(如果您真正想要的是从B中没有匹配行的行),请考虑在USEID列上进行该测试。看到我的答案了。这很奇怪。我读到连接总是比使用子查询快?你读信息的地方是错误的,特别是因为总是使用这个词。无论你想做什么,你都应该编写逻辑上最适合的查询,如果你不知道要做什么,就把优化留给SQL优化器我们的做法以及什么在数据库结构中表现最好。这很奇怪。我已经读到,连接总是比使用子查询更快?您读取信息的地方是错误的,特别是因为使用了“始终”这个词。无论您尝试做什么,您都应该编写逻辑上最适合的查询,并将优化留给SQL optimizer,如果您不知道自己在做什么以及数据库结构中什么性能最好。