說我有兩個名爲A(fields:id,phase,name)和B(fields:id,AID,APHASE,void)的表。如何編寫一個查詢,顯示錶A中沒有匹配記錄的表B中的記錄?
我需要顯示來自所有記錄,除了記錄,其中A.id = B.AID和A.phase = B.APHASE和無效= 0
環境是MySQL的。
說我有兩個名爲A(fields:id,phase,name)和B(fields:id,AID,APHASE,void)的表。如何編寫一個查詢,顯示錶A中沒有匹配記錄的表B中的記錄?
我需要顯示來自所有記錄,除了記錄,其中A.id = B.AID和A.phase = B.APHASE和無效= 0
環境是MySQL的。
SELECT *
FROM `A`
LEFT JOIN `B`
ON `A`.`id` = `B`.`id`
WHERE NOT (`A`.`id` = `B`.`AID` AND `A`.`phase` = `B`.`APHASE`
AND `void` = 0)
或:
SELECT *
FROM `A`
LEFT JOIN `B`
ON NOT (`A`.`id` = `B`.`AID`
AND `A`.`phase` = `B`.`APHASE`
AND `void` = 0)
不能保證第二個實際工作,它只是來到我的腦海
固定我想:\
SELECT * FROM A,B
其中
不(A.id = B.AID和A.phase = B.APHASE和空隙= 0)
我變老了:
不是一個很好的解決方案。暫時忽略階段和無效。假設表A中有一行id = 1,表B中有三行(id = 1,aid = 1),(id = 2,aid = 1),(id = 3,aid = 2 )。該查詢將生成結果行,但不應回答問題。 NOT EXISTS查詢將不會生成行 - 這是正確的結果。 – 2009-09-07 15:49:44
SELECT *
FROM A
WHERE NOT EXISTS
(
SELECT NULL
FROM B
WHERE b.aid = a.id
AND b.aphase = a.phase
AND b.void = 0
)
注意這個查詢將始終從A
正是1
或0
倍回報每行。
如果B (aid, aphase)
不是UNIQUE
,則LEFT JOIN
可以從A
多次返回行。
這些查詢有不同的語義,所以選擇一個正確的查詢是一個有效性問題,而不是性能問題。
至於性能,MySQL
將始終使用A
作爲主表,因爲它不能以NESTED LOOPS
之外的其他方式進行連接。
由於EXISTS
將始終會盡快恢復,因爲它找到第一個匹配的記錄,EXISTS
查詢總是會更有效率比LEFT JOIN
(只是因爲它返回至少不晚於LEFT JOIN
),在返回至多一個的費用記錄從A
。
SELECT
id, phase, name
FROM A
WHERE NOT EXISTS
(SELECT id FROM B WHERE AID=A.id AND APHASE=A.phase AND void=0)
嘿 - 兩張表加入a.id = b.id,還是加入'a.id = b.aid'?問題並不清楚 - 但你的答案是假設id行加入,而命名則表明否則。 – 2009-09-07 15:41:19
我不太確定,但我認爲第二個陳述描述了這個問題。如果它工作不正常,effkay總是可以回覆 – knittl 2009-09-07 15:44:50
有一個「他已經做了」的元素 - 你的答案被選中。第二個選項應該可能在SELECT列表中列出A. *。我擔心結果的基數(請參閱作者「答案」的評論)。我認爲'AND void = 0'位應該在'NOT(...)'括號內。 – 2009-09-07 15:48:19