用户(uid,姓名,生日,国家) 事件(eid,姓名,uid,日期) 客人(eid,uid,状态)
我需要找到在用户 uid=123 进行事件的同时进行事件的人。那么有没有更优雅的方法来做到这一点:
SELECT DISTINCT U1.uid, U1.name
FROM Users U1, Events E1, Events E
WHERE E.uid=123 AND E1.uid<>123 AND E1.date=E.date AND U1.uid=E1.uid
用户(uid,姓名,生日,国家) 事件(eid,姓名,uid,日期) 客人(eid,uid,状态)
我需要找到在用户 uid=123 进行事件的同时进行事件的人。那么有没有更优雅的方法来做到这一点:
SELECT DISTINCT U1.uid, U1.name
FROM Users U1, Events E1, Events E
WHERE E.uid=123 AND E1.uid<>123 AND E1.date=E.date AND U1.uid=E1.uid
您可以按如下方式重述您的查询:
SELECT uid, name FROM Users U WHERE uid <> 123 AND EXISTS (
SELECT * FROM Events E WHERE uid = U.uid AND EXISTS (
SELECT * FROM Events WHERE date = E.date AND uid = 123
)
)
请注意,您不需要DISTINCT
,因为没有JOIN
s 威胁要引入冗余行。
虽然这在逻辑上是表达查询的最简洁的方式,但您的 SQL 优化器可能不会原谅您的双重嵌套SELECT
s。如果是这样,您可以将最里面SELECT
的 s 展开为 a JOIN
。它不是很干净,但它会达到同样的效果。
如果这仍然不能产生可接受的性能,那么您可能会被原来的三向连接卡住。
应避免使用 distinct 作为删除重复结果的方法,因为它非常低效。它的工作原理是获取带有重复项的结果列表,然后删除这些重复项。您应该始终尝试设计一个查询,以首先不返回重复的结果。
此查询应返回您正在寻找的结果,而不会重复。
Select U.UID,U.Name
From Events E
Inner Join Events E1 on E1.uid<>E.uid and E1.Date=E.Date
Inner Join Users U on U.UID = E1.UID
Where E.UID=123
当我们对多列和 varchar 列使用 distinct 时,会导致查询性能变慢。您可以执行以下操作:
SELECT U1.uid, U1.name
FROM Users U1 I
INNER JOIN
(
SELECT DISTINCT E1.UID
FROM Events E1 INNER JOIN Events E ON E.uid = 123 AND E1.uid <> 123 AND E1.date = E.date
) AS A
WHERE
U1.uid = A.uid