MySQL多对多关系选择条件

发布于 2024-12-02 05:40:03 字数 1084 浏览 3 评论 0原文

我有两个表 books 和 Tags,它们通过表 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 来读取标签字段。 我尝试了三种不同的方法来过滤结果,但都不起作用。

  1. 使用地点:

    其中 flbdb_tags.name 如“%poetr%”

    但是,这意味着标签字段(使用 group_concat 组装的字段)仅填充此标签

  2. 使用具有

    flbdb_tags.name 类似于“%poetr%”

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

  3. 这不会返回所有标记为诗歌的书籍,因为在某些情况下,由于分组依据

    使用 group_concat 字段

    具有“%poetr%”等标签

    这实际上可以解决问题,但我需要进行不区分大小写的搜索,而 upper(tags) 不起作用

我希望我清楚我想要做什么。

谢谢

I have two tables books and tags which are in a many-to-many relationship via the table books_tags. What I want to do is select all books that have one or more tag(s) like '%tag%'. No problem. However, I also have a group_concat field which I want to be filled with all the tags that are related to the selected book.

My select query basically looks like this:

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;

This delivers the desired result if I don't have any conditions. I use PHP and json_decode to read the tags field.
I have tried three different ways to filter the results, but none of them works.

  1. use where:

    where flbdb_tags.name like '%poetr%'

    however, this means that the tags field (the one that is assembled using group_concat) is only filled with this tag

  2. use having

    having flbdb_tags.name like '%poetr%'

    this does not return all books tagged poetry, because in some cases the poetry tag is hidden behind another tag due to the group by

  3. use having on the group_concat field

    having tags like '%poetr%'

    this would actually do the trick, but I need to do the case-insensitive searching, and upper(tags) doesn't work

I hope it is clear what I want to do.

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

断爱 2024-12-09 05:40:03

有一个关系查询可以完全满足您的需要。

我们的见解是,过滤器标签是您的起点,您实际上需要从标签连接到书籍,然后再连接到标签。

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;

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

There is a relational query that does exactly what you need.

The insight is that the filter tag is your starting point, and you actually need to join from the tag to the book back on to tags.

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;

You need to join twice, not once since the tag you filter is a different set of data then all tags for a book.

岁月静好 2024-12-09 05:40:03

它对你有用吗?

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;

Will it work for you?

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;
独留℉清风醉 2024-12-09 05:40:03

不确定我是否清楚理解,但我会尝试包装您的原始选择并在包装选择中进行过滤

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%'

Not sure I clearly understand, but I'd try to wrap your original select and do the filtering in the wrapper select

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%'
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文