2014-03-04 44 views
0

我有一個表, 「上崗」,例如:如何檢索列表中包含* all *的記錄,而不是* any *?

+----+---------+------------+ 
| id | author | text | 
+----+---------+------------+ 
| 1 | bob |  hello | 
| 2 | jim |  hi bob | 
+----+---------+------------+ 

,也有 「標籤」,例如:

+----+--------------+ 
| id |  name  | 
+----+--------------+ 
| 1 | bugs  | 
| 2 | project_foo | 
| 3 | project_bar | 
+----+--------------+ 

,最後 「post_tags」,如:

+------+------+ 
| post | tag | 
+------+------+ 
| 1 | 1 | 
| 1 | 2 | 
| 2 | 1 | 
| 2 | 3 | 
+------+------+ 

帖子被標記有任意數量的標籤。通過上面的數據,對於我來說,查詢「給我列出所有標籤的帖子(1,2)」的最佳方式是什麼?這些將被標記爲「錯誤,project_foo」

一個加入搜索與「IN」,因爲它是返回匹配上市標籤的任何該職位不適合我的工作,所以我會收到「project_bar職位「錯誤帖子,即使它們甚至沒有被標記爲」project_foo「。如果帖子中至少有提到的標籤,那麼返回包含不在指定列表中的標籤的帖子將是完全正確的。所以「bug,project_foo,project_bar」會很好,但是「bugs,project_bar」不會。

我寧願用普通的ResultSet用法做到這一點,但我很喜歡在自定義的ResultSource :: View中做這件事。問題是,我無法弄清楚如何在原始SQL中執行此操作。

是否有一種實際的方法來做我試圖做的事情,或者是我的表設置只是爲了我想實現的目標?

謝謝。

+0

對於SQL語句,你可以使用'GROUP BY'和'HAVING'這樣的:'SELECT後FROM post_tags WHERE標記IN(1,2)GROUP BY帖子HAVING COUNT(post)= 2' – nwellnhof

回答

0

的SQL語句應該是:

SELECT post 
    FROM post_tags 
    WHERE tag IN (1, 2) 
GROUP BY post 
    HAVING COUNT(post) = 2 

所以像下面應該DBIx::Class工作:

my @tags = (1, 2); 

$schema->resultset('PostTags')->search({ 
    tag => { -in => \@tags }, 
}, { 
    columns => 'post', 
    group_by => 'post', 
    having => \[ 'COUNT(post) = ?', scalar(@tags) ], 
}); 

這隻會檢索後的ID。您可以嘗試添加連接或預取以在單個語句中檢索帖子內容。

0

我會去這個查詢。它會有很好的性能,但只有在確定只需要檢查兩個值時才能使用它。如果您的需求可能會擴大到包括第三甚至第四之一,那麼nwellnhof的回答是更好:

SELECT post 
    FROM post_tags a 
    WHERE EXISTS (
     SELECT 1 FROM post_tags b1 
     WHERE a.post = b1.post 
     AND b1.tag=1) 
    AND EXISTS (
     SELECT 1 FROM post_tags b2 
     WHERE a.post = b2.post 
     AND b2.tag=2); 
相關問題