[英]Mysql join query not excluding rows with same id if one row fails the join condition
表 A 有值
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 4 |
+----+
表 B 有值
+----+-----------+----------+
| id | parent_id | status |
+----+-----------+----------+
| 1 | 1 | started |
| 2 | 2 | stopped |
| 3 | 1 | stopped |
| 4 | 1 | stopped |
+----+-----------+----------+
A 关系 B 是 1:N
如何仅从表 A 中获取状态未启动的那些 id。
SELECT
id
FROM A
JOIN B ON A.id=B.parent_id and B.status <> 'started';
当我运行上述查询时,我得到了这个结果
+----+
| id |
+----+
| 1 |
| 2 |
+----+
它不仅显示值 2,还显示 1。 我写的查询有什么问题?
显示其状态未启动。
SELECT A.id FROM A JOIN B ON A.id=B.parent_id and B.status != 'started'
Output:
+----+
| id |
+----+
| 2 |
| 1 |
| 1 |
+----+
在您的查询中返回 parent_id 2 因为也已停止您可以尝试使用 not in with subquery for states
SELECT id
FROM A
JOIN B ON A.id=B.parent_id
WHERE B.parent_id NOT IN (
select parent_id
from B
B.status = 'started'
)
我会使用not exists
:
select a.id
from a
where not exists (select 1 from b where b.parent_id = a.id and b.status = 'started')
这会从a
中过滤掉b
中任何子记录的状态为已启动的行。
查询的“未开始”部分将表 B 过滤为以下内容:
+----+-----------+----------+
| id | parent_id | status |
+----+-----------+----------+
| 2 | 2 | stopped |
| 3 | 1 | stopped |
| 4 | 1 | stopped |
+----+-----------+----------+
然后,您的联接正在查找表 A 中的 id 与表 B 的父 ID 匹配的行 - 它正确返回(但不计算 1 两次)
如果您希望前半部分返回:
+----+-----------+----------+
| id | parent_id | status |
+----+-----------+----------+
| 2 | 2 | stopped |
+----+-----------+----------+
PLUS the rows from table A not referred to in table B....
那么上面GMB的回答是正确的——
select a.id
from a
where not exists (select 1 from b where b.parent_id = a.id and b.status = 'started')
这是一个小提琴。 https://sqltest.net/#1005425
但是,正如建议的那样,您最终可能会在表 B 中出现很多不必要的重复 - 许多行表示开始和停止,不一定按时间顺序排列(例如 - A.id=1 的第一条记录表明它已经开始,第 3 条和第 4 条记录(大概是后来输入的)停止了它,但是您将排除此记录以启动它。
为什么不改变你的表结构来更新单行呢?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.