【发布时间】:2009-09-07 15:14:58
【问题描述】:
假设我有两个名为 A(字段:id、phase、name)和 B(字段:id、AID、APHASE、void)的表。
我需要显示 A 中的所有记录,除了 A.id = B.AID 和 A.phase = B.APHASE 和 void = 0 的记录。
环境是 MySQL。
【问题讨论】:
假设我有两个名为 A(字段:id、phase、name)和 B(字段:id、AID、APHASE、void)的表。
我需要显示 A 中的所有记录,除了 A.id = B.AID 和 A.phase = B.APHASE 和 void = 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
id, phase, name
FROM A
WHERE NOT EXISTS
(SELECT id FROM B WHERE AID=A.id AND APHASE=A.phase AND void=0)
【讨论】:
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返回最多一条记录为代价。
【讨论】:
NOT EXISTS 可能会很慢
@knittl:在MySQL(即MySQL)中,它不会比LEFT JOIN(即LEFT JOIN)慢。
我猜是固定的:\
从 A、B 中选择 *
在哪里
not(A.id = B.AID and A.phase = B.APHASE and void = 0)
我变老了:|
【讨论】: