2013-01-09 47 views
0

我有如下表我想做一個搜索:和MySQL的搜索多對多表

Table A 
+----+----------------------------+ 
| ID | description    | 
+----+----------------------------+ 
| 0 | horse going bad   | 
| 1 | Older Years of Resolutions | 
| 2 | The knockknock pirate  | 
| 3 | The Wish list    | 
| 4 | list that's no list  | 
+----+----------------------------+ 

table TAGS 
+----+------------+ 
| ID | tag  | 
+----+------------+ 
| 0 | list  | 
| 1 | knockknock | 
+----+------------+ 

table TAGLINKS 
+-------+--------+ 
| TAGID | JOKEID | 
+-------+--------+ 
| 0 | 2 | 
| 0 | 3 | 
+-------+--------+ 

當我這樣做搜索:

select A.* from tags 
    join taglinks on tagid=tags.id 
    join A on A.id=jokeid 
where tag in ('list','knockknock') 

讓我在一個所有條目在他們的標籤(或兩者)中都有'列表'或'敲敲'(2,3)。我在尋找的是從A表中獲取連接到BOTH列表和敲標記標記(僅限2)的條目的查詢。

我也從表A,這是一件好事採取在考慮的描述直接搜索Unioning這個數據..

現在我有:

select A.* from tags 
    join taglinks on tagid=tags.id 
    join A on A.id=jokeid 
where tag in ('list','knockknock') 

UNION 

select * from A where locate('list',description) and locate('knockknock',description) 

但我也從表A中拿到3,我想只有2

回答

2

要確保所有有兩個標籤'list', 'knockknock'你應該添加GROUP BY子句HAVING

... 
WHERE tag in ('list', 'knockknock') 
GROUP BY tag 
HAVING COUNT(tag) = 2) 

喜歡的東西:

SELECT A.* 
FROM tags 
INNER JOIN taglinks ON tagid = tags.id 
INNER JOIN A on A.id=jokeid 
WHERE id IN (SELECT id 
      FROM tags 
      WHERE tag in ('list', 'knockknock') 
      GROUP BY tag 
      HAVING COUNT(tag) = 2) 
1

這是在看標籤爲一組,並尋找該組的屬性的示例。我喜歡使用SQL的聚合函數來處理這個問題,特別是having子句。

select A.* 
from tags join 
    taglinks 
    on tagid=tags.id join 
    A on A.id=jokeid 
group by A.id 
having max(tag = 'list') = 1 and 
     max(tag = 'knockknock') = 1 

(注:此使用兩個MySQL特定的語法約定group by只在id列;其餘的是「隱藏列」而且,表達tag = 'list'被視爲一個真正的價值,所以。 ,不需要完全case語句)

順便說一句,這個切換到一個標籤或其他容易:

select A.* 
from tags join 
    taglinks 
    on tagid=tags.id join 
    A on A.id=jokeid 
group by A.id 
having max(tag = 'list') = 1 or 
     max(tag = 'knockknock') = 1