SQL查询:这个查询对吗?更好的写作方式?

时间:2013-06-30 07:46:13

标签: sql

用户( 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

3 个答案:

答案 0 :(得分:2)

您可以按如下方式重新提问:

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威胁导致冗余行。

虽然这在逻辑上是表达查询的最简洁方式,但您的SQL优化器可能不会原谅双重嵌套SELECT。如果是这样,您可以将最里面的SELECT展开为JOIN。它不是那么干净,但它会达到同样的效果。

如果仍然没有产生可接受的性能,那么您可能会陷入原始的三向连接。

答案 1 :(得分:0)

当我们使用distinct与多列和varchar列时,它将导致较慢的查询性能。你可以做以下事情:

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

答案 2 :(得分:0)

应避免使用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