2013-10-11 58 views
0

我有一個表是這樣的:如何選擇2列應匹配多行的不同行?

id | user_id | param_id | param_value 
1  1   44   google 
2  1   45   adTest 
3  1   46   Campaign 
4  1   47   null 
5  1   48   null 
6  2   44   google 
7  2   45   adAnotherTest 
8  2   46   Campaign2 
9  2   47   null 
10  2   48   null 

我想獲取所有user_ids其中(param_id = 44和param_value =谷歌)AND(param_id = 45和param_value = ADTEST)。所以上面的where子句應該只給user_id = 1而不是user_id = 2。他們在param_id 44都有google,但只有用戶1在param_id = 45時有param_value adTest。

問題是未來可能會增加更多參數。我需要找到一個動態查詢。在這裏我已經tryed:

SELECT DISTINCT up.user_id FROM user_params AS up 

        LEFT JOIN user_params AS upp ON up.id = upp.id 

        WHERE up.param_id IN (?,?) 

        AND upp.param_value IN (?,?) 

回答

3
SELECT DISTINCT up.user_id 
FROM user_params AS up 
LEFT JOIN user_params AS upp ON up.id = upp.id 
group by up.user_id 
having sum(param_id = 44 AND param_value = 'google') >= 1 
and sum(param_id = 45 AND param_value = 'adTest') >= 1 
+0

Ty爲快速回答,briliant –

+0

好的+1並根據您的回答發佈升級 –

0

如果要優化這個應該給予同樣的結果,而不需要一個LEFT JOIN表掃描(感謝克林斯曼d具有部分

SELECT 
user_id 

FROM 
user_params 

WHERE 
    param_id IN(44, 45) 
AND 
    param_value IN('google', 'adTest') 

GROUP BY 
user_id 

HAVING 
    sum(param_id = 44 AND param_value = 'google') >= 1 
    AND 
    sum(param_id = 45 AND param_value = 'adTest') >= 1 
; 

看到http://sqlfiddle.com/#!2/17b65/4用於演示

2

另一種方式:

SELECT -- DISTINCT 
    up1.user_id 
FROM 
    user_params AS up1 
    JOIN 
    user_params AS up2 
     ON up1.user_id = up2.user_id 
WHERE 
    up1.param_id = 44 AND up1.param_value = 'google' 
    AND 
    up2.param_id = 45 AND up2.param_value = 'adTest' ; 

你不需要DISTINCT,如果有上(user_id, param_id)

對於效率的UNIQUE約束,對(param_id, param_value, user_id)


你正在處理被稱爲問題「關係處添加一個索引「@Erwin Brandstetter在這裏有一個很好的答案:How to filter SQL results in a has-many-through relation,有很多方法來編寫這樣的查詢,以及性能測試。

測試在Postgres的做了一些疑問沒有在MySQL甚至運行,但至少有一半人都跑和效率將是許多人相似。

+0

Distinct was removed :),ty for the notice。但是你的回答並不是那麼高效,因爲查詢是動態的,就像我在問題中所說的那樣。如果我添加更多和更多的連接將不是一個好的解決方案。接受的解決方案對於動態查詢來說是最好的(許多param_id參數值對要匹配) –

+0

它可能不好,因爲您必須每次構建不同的查詢,因此它需要動態解決方案。但是,你真的測試過效率還是隻是猜測?我的估計是,聯接越多,查詢得到的效率就越高。 –

+0

何時有12 ++連接的查詢有效? :) –