2017-01-24 8 views
1

私はこのようなクエリがある:タグを検索するときに、そのタグのすべてを含む記事を取得するにはどうすればよいですか?

select ..., 
group_concat(tag.string separator '|') as tags 
from article a 
left join articletag on a.id = articletag.a_id 
left join tag on tag.id = articletag.t_id 
where /* OR product of (column like %term%) */ 
group by a.id 

問題はマッチがタグに発生したとき、それは私の「グループ化」を破壊し、一列のみを返すということです。

少なくとも1つの行がマッチすると、グループ全体がどのようにパフォーマンスが低下しますか?


例:それはtag.string like '%tag 1%'が含まれている場合、現在のクエリが(2, 'article 2', 'long content', 'tag 1')を返します

article 
id | title  | content 
2 | article 2 | long content 

tag 
id | string 
1 | tag 1 
2 | tag 2 
4 | tag 4 

articletag 
a_id | t_id 
2 | 1 
2 | 2 
2 | 4 

または(2, 'article 2', 'long content', 'tag 1|tag 2')'tag 2'

を検索するときに、私はあなたの現在のアプローチと(2, 'article 2', 'long content', 'tag 1|tag 2|tag 4')

+2

いくつかのサンプルをデータはここで長い道のりになります。 –

+0

私はそれをもっと一般的に書こうとしましたが、今追加するために編集します – Artis

答えて

2

問題は、あなたがarticleテーブルのid列によってグループ化されていますが、非集約レコードを選択していることである取得したいですGROUP BYも使用しています。これは、省略記号...しか持たないオリジナルのクエリではやや隠れていますが、そこに問題があります。

代わりに、別のサブクエリにパイプで区切られたタグ文字列を計算し、次いでarticleテーブルこのバック参加:ここで

SELECT t1.*, t2.tags 
FROM article t1 
LEFT JOIN 
(
    SELECT at.a_id, 
      GROUP_CONCAT(COALESCE(t.string, 'NA') ORDER BY t.string SEPARATOR '|') AS tags 
    FROM articletag at 
    LEFT JOIN tag t 
     ON at.t_id = t.id 
    GROUP BY at.a_id 
) t2 
    ON t1.id = t2.a_id 

デモ:

SQLFiddle

+0

ありがとう! Btw、少なくとも私がサブクエリと比較したときにパフォーマンスの影響を知ることは起こりますか? – Artis

+1

難しい質問です。 _only_ idと連結された文字列が必要な場合は、元のクエリが機能しているはずです。私の答えでは、非相関サブクエリを 'article'テーブルに戻すために基本的に追加のテーブルスキャンがあります。これは比較的軽微で、 'article'の他のフィールドが必要な場合は、元の方法は本当にオプションではありません。 –

関連する問題