2013-06-30 100 views
0

用户(UID,姓名,生日,国家) 活动(EID,名称,UID,日期) 客人(EIDUID,状态)SQL查询:这个查询是否正确?更好的方式来写它?

我需要找人谁在同一时间做了事件用户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 
+0

http://codereview.stackexchange.com/ – mishik

+2

您应该停止使用过时的隐式连接并使用显式的“JOIN”代替 –

+0

'guests'表的相关性是什么? – wildplasser

回答

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 
+0

这个答案对你有帮助吗? –

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 
+0

OP希望用户在结果中,而不是事件。 –

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 s展开成JOIN。它不是很干净,但它会达到同样的效果。

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

+0

@wildplasser:OQ从Users中选择不同的'uid' /'name'('DISTINCT'使连接表的存在无关紧要)。 Mine从用户中选择非独特的'uid' /'name'并且没有连接。如果'{uid,name}'不是超级键,这些只能产生不同的结果。由于'uid'几乎肯定是主键,这似乎不太可能。 –

相关问题