###前提・実現したいこと
MySQLのwhereで「タグ1とタグ2を持つ記事」などの条件で取得しています
下記のソースコードで取得結果となるIDは 2,4,8,9,10 という5件です
この取得結果に、「このレコードはタグ1を持つ記事として取得されました」ということを示すことはできますか?
###最終的な目的
最終的な目的としてはフロントへの出力を次のように、タグごとにわけることです
------------
【タグ1を持つ記事一覧】
2,4,8,10
【タグ2を持つ記事一覧】
9
------------
###ソースコード
現状はこのようなSQLを書いていて、
sql
1select p.ID, p.contents 2from posts p 3left join tag_relations tr ON tr.contents_ID = p.ID 4left join tags t ON t.ID = tr.tags_ID 5where t.tag_name IN ( 'タグ1', 'タグ2' ) # 指定タグを持っている 6AND p.ID NOT IN ( 1 ) # 指定記事を除外 7group by p.ID
###ソースコードの結果
で、次のレコードが取得される状況ですが、
ID | contents |
---|---|
2 | #タグ1 を持っている記事2の本文です |
4 | #タグ1 と #タグ3 と #タグ4 を持っている記事4の本文です |
8 | #タグ1 を持っている記事8の本文です |
9 | #タグ2 と #タグ4 を持っている記事9の本文です |
10 | #タグ1 と #タグ2 と #タグ6 を持っている記事10の本文です |
###欲しい結果
ここに次のように「このレコードはタグ1を持つ記事として取得されました」などの「取得経緯のtag_ID」を示したいのです
ID | contents | 取得経緯のtag_ID |
---|---|---|
2 | #タグ1 を持っている記事2の本文です | 1 |
4 | #タグ1 と #タグ3 と #タグ4 を持っている記事4の本文です | 1 |
8 | #タグ1 を持っている記事8の本文です | 1 |
9 | #タグ2 と #タグ4 を持っている記事9の本文です | 2 |
10 | #タグ1 と #タグ2 と #タグ6 を持っている記事10の本文です | 1 |
【※】post_ID=10はタグ1もタグ2も持っていますが、タグ1側を優先したいです
###テーブル
そしてテーブルはこうです
sql
1-- 記事 2CREATE TABLE posts 3 (`ID` int, `user_ID` int, `contents` varchar(100)) 4; 5INSERT INTO posts 6 (`ID`, `user_ID`, `contents`) 7VALUES 8 (1, 10, '#タグ1 と #タグ2 を持っている記事1の本文です'), 9 (2, 20, '#タグ1 を持っている記事2の本文です'), 10 (3, 30, '記事3の本文です'), 11 (4, 10, '#タグ1 と #タグ3 と #タグ4 を持っている記事4の本文です'), 12 (5, 30, '#タグ5 を持っている記事5の本文です'), 13 (6, 40, '記事6の本文です'), 14 (7, 10, '記事7の本文です'), 15 (8, 50, '#タグ1 を持っている記事8の本文です'), 16 (9, 10, '#タグ2 と #タグ4 を持っている記事9の本文です'), 17 (10, 20, '#タグ1 と #タグ2 と #タグ6 を持っている記事10の本文です') 18; 19 20-- タグ 21CREATE TABLE tags 22 (`ID` int, `tag_name` varchar(100)) 23; 24INSERT INTO tags 25 (`ID`, `tag_name`) 26VALUES 27 (1, 'タグ1'), 28 (2, 'タグ2'), 29 (3, 'タグ3'), 30 (3, 'タグ4'), 31 (3, 'タグ5'), 32 (3, 'タグ6') 33; 34 35-- タグリレーション 36CREATE TABLE tag_relations 37 (`tags_ID` int, `contents_ID` int ) 38; 39INSERT INTO tag_relations 40 (`tags_ID`, `contents_ID` ) 41VALUES 42 # contents_ID=1が、tag_ID=1とtag_ID=2を持っている 43 (1, 1), (2, 1), 44 # contents_ID=2が、tag_ID=1を持っている 45 (1, 2), 46 # contents_ID=4が、tag_ID=1とtag_ID=3とtag_ID=4を持っている 47 (1, 4), (3, 4), (4, 4), 48 # contents_ID=5が、tag_ID=5を持っている 49 (5, 5), 50 # contents_ID=8が、tag_ID=1を持っている 51 (1, 8), 52 # contents_ID=9が、tag_ID=2とtag_ID=4を持っている 53 (2, 9), (4, 9), 54 # contents_ID=10が、tag_ID=1とtag_ID=2とtag_ID=6を持っている 55 (1, 10), (2, 10), (6, 10) 56;
###試したこと
最終的な目的のためには、クエリを一つにまとめずアプリケーション側で二つ実行すればいいのですが、まずそれはなしで、一つのクエリで実現したいと考えています
ならばと、二つをそのまま一つにまとめて、つまりunionで次のようにまとめてみれば実現できるか?と思ったのですが…
惜しくも【※】の部分が欲しい結果とは微妙に異なりまして、ID=10について、「取得経緯のtag_ID」が1でなく2になってしまう結果でした(そもそもunionはあまり推奨されないようですし、他の方法を探しています)
sql
1select p.ID, p.contents, '1' AS 取得経緯のtag_ID 2from posts p 3left join tag_relations tr ON tr.contents_ID = p.ID 4left join tags t ON t.ID = tr.tags_ID 5where t.tag_name IN ( 'タグ1' ) # 指定タグを持っている 6AND p.ID NOT IN ( 1 ) # 指定記事を除外 7group by p.ID 8 9union 10 11select p.ID, p.contents, '2' AS 取得経緯のtag_ID 12from posts p 13left join tag_relations tr ON tr.contents_ID = p.ID 14left join tags t ON t.ID = tr.tags_ID 15where t.tag_name IN ( 'タグ2' ) # 指定タグを持っている 16AND p.ID NOT IN ( 1 ) # 指定記事を除外 17group by p.ID
回答2件
あなたの回答
tips
プレビュー