2012-11-20 73 views
1

我試圖搜索所有具有所有已輸入標籤的用戶,但它通過查找同一列來搜索它們。通過查詢同一列獲取具有所有輸入值的所有行

SELECT u.*, t.* FROM user u 
LEFT JOIN user_tags ut ON u.id = ut.user_id 
LEFT JOIN tags t ON ut.tag_id = t.id 
WHERE t.name = tag1 AND t.name = tag2 

我按標籤僅搜索和每個用戶都必須全部錄入的標籤,而不僅僅是1.我使用PHP基於值的數量再添及條款進入,所以如果有3個值將如下所示:

SELECT u.*, t.* FROM user u 
LEFT JOIN user_tags ut ON u.id = ut.user_id 
LEFT JOIN tags t ON ut.tag_id = t.id 
WHERE t.name = tag1 AND t.name = tag2 AND t.name = tag3 

t.name只包含1個標記名稱,而不是以逗號分隔的值。標籤名稱是通過user_tags錶鏈接到每個用戶,每個用戶ID可以在多個標籤ID,像這樣:

user_id | tag_id 
40  | 3 
40  | 4 
41  | 1 
41  | 2 
41  | 3 

而我當前的查詢返回任何內容,因爲沒有列具有所有3個標籤名稱。

+0

所以我猜t.name是一個逗號分隔的字段?必須使用'LIKE'進行字符串搜索 – wesside

+0

您可以告訴我們更多關於存儲在t.name中的內容嗎? – Toby

+2

您可以添加具有預期結果的樣本記錄嗎? –

回答

1

最簡單的解決辦法是以下哪裏是相同的'count'是您要查詢的標籤數量,因此您只會獲得擁有所有指定標籤的用戶。

SELECT u.*, count(*) as `count` 
FROM `user` u 
    JOIN `user_tags` ut ON ut.`user_id`=u.`id` 
    JOIN `tags` t ON t.`id`=ut.`tag_id` 
WHERE t.`name`='tag1' OR t.`name`='tag2' 
GROUP BY u.`id` 
HAVING `count` = 2 
+0

謝謝,這正是我正在尋找的。 – user1838867

1

你可以做這樣的事情。它只會返回具有全部3個標籤的用戶標識。

SELECT u.id 
FROM  user u 
      LEFT JOIN user_tags ut ON u.id = ut.user_id 
      LEFT JOIN tags t ON ut.tag_id = t.id 
GROUP BY u.id 
HAVING  SUM(CASE WHEN t.name = tag1 THEN 1 ELSE 0 END) > 0 
      AND SUM(CASE WHEN t.name = tag2 THEN 1 ELSE 0) > 0 
      AND SUM(CASE WHEN t.name = tag3 THEN 1 ELSE 0) > 0 
+0

很好的答案。然而,使用內部連接和一個額外的ON子句會稍快些,例如:INNER JOIN user_tags ut ON u.id = ut.user_id INNER JOIN標記t ON ut.tag_id = t.id AND t.name IN(tag1, tag2,tag3) - 在使用HAVING子句之前,這將消除沒有標籤1,2或3的用戶。 –

+0

好點。我在想,只有3個標籤。但有可能有更多。我無法真正瞭解這個問題。 – Tom

+0

不僅如此,但那些沒有指定標籤的用戶呢?你想在組隊之前消除它們。還請注意,我在下面添加了另一個不使用組的應用程序,這應該是非常高性能的。 –

0

允許使用GROUP_CONCAT ...

SELECT 
    u.* 
FROM 
    user u 
    JOIN user_tags ut ON ut.user_id = y.id 
    JOIN tags t ON t.id = ut.tag_id 
WHERE 
-- limit only the tags you want 
    t.name IN (tag1, tag2, ...) 
GROUP BY 
    u.id 
HAVING 
    GROUP_CONCAT(t.name ORDER BY t.name SEPARATOR ',') = 'tag1,tag2,...' 

需要注意的是,在有節,標記順序應在條件兩邊

+0

讓我們殺死數據庫... –

相關問題