2011-08-31 126 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%'