2013-06-30 144 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'幾乎肯定是主鍵,這似乎不太可能。 –

相關問題