MySQL多对多关系选择条件

时间:2011-08-31 16:36:15

标签: mysql select group-by many-to-many relationship

我有两本桌子书籍和标签,这些书籍和标签通过表books_tags呈多对多关系。我想要做的是选择所有包含一个或多个标签的书籍,例如'%tag%'。没问题。但是,我还有一个group_concat字段,我想填充所有与所选书籍相关的标签。

我的选择查询基本上如下所示:

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来读取tags字段。 我尝试了三种不同的方法来过滤结果,但没有一种方法可以使用。

  1. 使用位置:

    where flbdb_tags.name like '%poetr%'

    但是,这意味着标记字段(使用group_concat汇编的字段)仅填充此标记

  2. 使用

    having flbdb_tags.name like '%poetr%'

    这并不会返回所有标记为诗歌的书籍,因为在某些情况下,诗歌标签会隐藏在另一个标签后面,因为

  3. 在group_concat字段上使用

    having tags like '%poetr%'

    这实际上可以解决问题,但是我需要进行不区分大小写的搜索,并且上层(标记)不起作用

  4. 我希望很清楚我想做什么。

    由于

3 个答案:

答案 0 :(得分: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;

答案 1 :(得分: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%'

答案 2 :(得分: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;

您需要加入两次,而不是一次,因为您过滤的标记是一组不同的数据,然后是一本书的所有标记。