0

用户(uid,姓名,生日,国家) 事件(eid,姓名,uid,日期) 客人(eiduid,状态)

我需要找到在用户 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
4

3 回答 3

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,因为没有JOINs 威胁要引入冗余行。

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

如果这仍然不能产生可接受的性能,那么您可能会被原来的三向连接卡住。

于 2013-06-30T09:04:31.057 回答
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
于 2013-06-30T08:12:23.587 回答
0

当我们对多列和 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
于 2013-06-30T08:00:28.260 回答