2011-08-31 129 views
0

我有两个表格书籍和标签,它们通过表books_tags处于多对多的关系。我想要做的是选择所有具有一个或多个标记(如'%tag%')的图书。没问题。但是,我也有一个group_concat字段,我想填充与选定图书相关的所有标签。MySQL多对多关系选择条件

我的选择查询基本上是这样的:

select 
    flbdb_books.id, 
    flbdb_books.title, 
    flbdb_tags.id, 
    flbdb_tags.name, 
    group_concat(distinct concat('["', flbdb_tags.id, '","', flbdb_tags.name, '"]') separator ',') as tags 

from 
    flbdb_books 

join flbdb_books_tags 
    on flbdb_books.id = flbdb_books_tags.book_id 
join flbdb_tags 
    on flbdb_tags.id = flbdb_books_tags.tag_id 

group by flbdb_books.id; 

这可以实现所需的结果,如果我没有任何条件。我使用PHP和json_decode来读取标签字段。 我尝试过三种不同的方法来过滤结果,但没有一个能起作用。

  1. 用途,其中:

    where flbdb_tags.name like '%poetr%'

    然而,这意味着该标记字段(即,使用GROUP_CONCAT组装所述一个)仅填充有该标签的

  2. 具有

    使用

    having flbdb_tags.name like '%poetr%'

    这不返回所有书籍标记诗歌,因为在某些情况下,诗歌标签背后却隐藏着另一个标签由于组具有

    having tags like '%poetr%'

    这将在GROUP_CONCAT场

  3. 使用实际上做的伎俩,但我需要做的不区分大小写的搜索,和上(标签)不起作用

我希望这是清楚我想做的事情。

谢谢

+1

为什么你的#3解决方案没有工作?像这样做一个类似的搜索是不区分大小写的。使用''%poetry%''',''%POETRY%''或甚至'%pOeTrY%'没有区别' –

+0

这可能是使用'inner_join'的好例子。 –

+0

@布莱恩我不知道为什么,但在这种情况下,像不区分大小写。也许是因为group_concat? – flammel

回答

0

有一个关系查询,做正是你需要的。

洞察力是过滤器标签是您的出发点,而您实际上需要从标签加入书本,再加入标签。

select 
books.id, 
books.title, 
tags.id, 
tags.name, 

group_concat(distinct concat('["', tags.id, '","', tags.name, '"]') separator ',') as tags 

from flbdb_tags filter_tag 

join flbdb_books_tags filter_book_tags 
    on filter_tag.id = filter_book_tags.tag_id 

join flbdb_books books 
    on filter_book_tags.book_id = books.id 

join flbdb_books_tags books_tags 
    on books.id = books_tags.book_id 

join flbdb_tags tags 
    on tags.id = books_tags.tag_id 

where filter_tag.name like '%poetr%' 

group by books.id; 

需要,因为你过滤器是一组不同的数据,那么所有标签一本书标签加入了两次,一次也没有。

+0

谢谢!这就像一个魅力! – flammel

0

它适合你吗?

select 
flbdb_books.id, 
flbdb_books.title, 
COUNT(CASE 
WHEN flbdb_tags.name LIKE '%poetr%' THEN 1 
END) as num_poetry, 
group_concat(distinct concat('["', flbdb_tags.id, '","', flbdb_tags.name, 
'"]')   separator ',') as tags 
from 
flbdb_books 

join flbdb_books_tags 
on flbdb_books.id = flbdb_books_tags.book_id 
join flbdb_tags 
on flbdb_tags.id = flbdb_books_tags.tag_id 

group by flbdb_books.id 
HAVING num_poetry >0; 
0

不知道我清楚的明白,但我想尝试来包装你原来的选择,做在包装的过滤选择

select * from (
select 
    flbdb_books.id, 
    flbdb_books.title, 
    flbdb_tags.id, 
    flbdb_tags.name, 
    group_concat(distinct concat('["', flbdb_tags.id, '","', flbdb_tags.name, '"]') separator ',') as tags 
from 
    flbdb_books 
join flbdb_books_tags 
    on flbdb_books.id = flbdb_books_tags.book_id 
join flbdb_tags 
    on flbdb_tags.id = flbdb_books_tags.tag_id 
group by flbdb_books.id) inner_select 
where upper(inner_select.name) like '%herpderp%'