2013-01-09 48 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