2016-11-11 58 views
1

假設我有如下表結構:如何基於對列(一個自己SELECT的結果)中選擇數據?

TABLE session 
    int entity_id 
    int user_id 
    int status 

TABLE entity_user 
    int entity_id 
    int user_id 
    int target 

session表由不同的實體不同的用戶登錄互動。 entity_user表指定哪些用戶有權訪問每個實體。重要的是,每個用戶都可以訪問多個實體。

我想根據一些標準從session表中選擇(實體,用戶)對,例如。一個特定的狀態。說完這些檢索對,我想查找相應的目標在entity_user表一對。

有沒有辦法在SQL中乾淨地做到這一點,理想情況下只有一個查詢?

我的解決方案到目前爲止是選擇對,做一些脫機文本處理連接它們(與分隔符),然後使用該文本。因此:

SELECT entity_id, user_id FROM session WHERE status = 100; 
-- Returns (101, 234), (204, 157), etc. 
-- Post-process this result using # as a separator 
SELECT entity_id, user_id, target FROM entity_user 
    WHERE CONCAT(user_id, '#', entity_id) IN ('101#234', '204#157', ...) 

這工作,但我覺得應該是在SQL做這個方式。有什麼建議麼?

+0

@ e4c5還沒有,但我會。 – dave

回答

1

可與子查詢和加入的組合來完成。

SELECT * FROM (
    SELECT entity_id, user_id FROM session WHERE status = 100) as s 
LEFT JOIN entity_user ON s.entity_id = entity_user.entity_id and s.user_id = entity_user.user_id 
+0

與其他非常緩慢的解決方案相比,此解決方案非常快速地完成。所以這是我的選擇。 – dave

+0

很高興有幫助 – e4c5

1

你可以在MySQL中使用IN雙:

SELECT entity_id, user_id, target 
FROM entity_user 
WHERE (user_id, entity_id) IN (SELECT user_id, entity_id FROM session WHERE status = 100); 

出於性能考慮,我建議在session(session, entity_id, user_id)的索引。你也可以使用一個join

SELECT eu.entity_id, eu.user_id, eu.target 
FROM entity_user eu JOIN 
    session s 
    USING (user_id, entity_id) 
WHERE s.status = 100; 

對於這一點,在session(status, user_id, entity_id)entity_user(user_id, entity_id)指標將是有益的。

+0

我這個做了嘗試,但在查詢幾分鐘後沒有完成,所以我停止了。作爲參考,單獨運行時,內部查詢大約需要40-50秒,而我早期的基於CONCAT的查詢大約需要10秒。我希望純粹的解決方案能夠花費相當的時間。有什麼想法嗎? – dave

+0

@dave。 。 。我注意到這兩列在''in'元組和子查詢中的順序不同。這可能會解決您的問題。我還用索引建議更新了這個問題。 –

+0

感謝您的跟進。我檢查過,並且在這兩種情況下我都有相同順序的元組,所以這不是問題。您可能正在建立索引的正確軌道。我認爲我無法爲這種特殊情況下的生產添加索引。 – dave

相關問題