[英]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.