###実現したいこと
action_table
というテーブルにfavorite
というアクションが記録されています。
サイト閲覧者をuser_id=1
と仮定し、彼のfavorite
リストを作りたいです。
###発生している問題
favorite
リストは大体できたのですが、
【問題➀】follow_date
とfavorite_date
がnull
となってしまうこと。
【問題➁】「クジラの生活」の方だけfavorite_tags
が取得できないこと。
が問題となっています。
###該当のテーブル
長くてすみませんが、現在値として仮定したCREATE TABLE
を掲載させて頂きます。
テーブルは6つですが、大きく次の3つに分類されます。
分類 | テーブル名 |
---|---|
『自社ユーザーが実行したアクション』 | action_table |
『自社ユーザー以外のコンテンツ』 | content_table とcontent_sub_table |
『自社ユーザー』 | own_user_table とown_user_sub_table |
これらからaction_table
のfavorite
リストを作るわけですが、
favorite
の対象がtarget_type='user'
かつtarget_studio='own'
のときには『自社ユーザー』のテーブルを参照し、それ以外は『自社ユーザー以外のコンテンツ』を参照する予定です。
以下CREATE TABLE
です。
SQL
1# action_table 2# 自社ユーザーが実行したアクション 3CREATE TABLE action_table 4 (`action_id` int, `action_name` text, `action_date` text, `actor_id` int, `target_id` int, `target_type` text, `target_studio` text, `favorite_tags` text) 5; 6INSERT INTO action_table 7 (`action_id`, `action_name`, `action_date`, `actor_id`, `target_id`, `target_type`, `target_studio`, `favorite_tags`) 8VALUES 9 (1, 'follow', '2020-01-01 01:01:01', 1, 3, 'user', 'own', ''), 10 (2, 'favorite', '2020-02-02 01:02:02', 1, 4, 'documentaly', 'nhk', '"["ドキュメンタリー","クジラ"]"'), 11 (3, 'favorite', '2020-03-03 03:03:03', 1, 3, 'user', 'own', '"["田中兄弟"]"'), 12 (4, 'block', '2020-04-04 04:04:04', 4, 1, 'user', 'own', ''), 13 (5, 'favorite', '2020-05-05 05:05:05', 1, 4, 'user', 'own', ''), 14 (6, 'follow', '2020-06-06 06:06:06', 1, 2, 'user', 'own', '') 15; 16 17# content_table 18# 自社ユーザー(own_user)以外のコンテンツの基本情報 19CREATE TABLE content_table 20 (`content_id` int, `content_type` text, `content_text` text) 21; 22INSERT INTO content_table 23 (`content_id`, `content_type`, `content_text`) 24VALUES 25 (1, 'comment', 'こんにちは'), 26 (2, 'review', 'まぁまぁ'), 27 (3, 'user', '山田花子です'), 28 (4, 'documentaly', 'クジラの生活'), 29 (5, 'news', 'ワールドビジネスニュース') 30; 31 32# content_sub_table 33# 自社ユーザー(own_user)以外のコンテンツの補足情報 34CREATE TABLE content_sub_table 35 (`sub_id` int, `content_id` int, `sub_key` text, `sub_val` text) 36; 37INSERT INTO content_sub_table 38 (`sub_id`, `content_id`, `sub_key`, `sub_val`) 39VALUES 40 (1, 1, 'studio_name', 'own'), 41 (2, 1, 'content_url', 'own/comment/1'), 42 (3, 2, 'studio_name', 'nhk'), 43 (4, 2, 'content_url', 'nhk/review/2'), 44 (5, 2, 'review_score', '5'), 45 (6, 3, 'studio_name', 'fuji'), 46 (7, 3, 'content_url', 'fuji/user/hanako'), 47 (8, 3, 'unique_name', 'hanako'), 48 (9, 3, 'nick_name', '山田花子'), 49 (10, 4, 'studio_name', 'nhk'), 50 (11, 4, 'content_url', 'nhk/documentaly/クジラの生活'), 51 (12, 4, 'airtime', '06:00'), 52 (13, 5, 'studio_name', 'asahi'), 53 (14, 5, 'content_url', 'asahi/news/ワールドビジネスニュース'), 54 (15, 5, 'airtime', '22:00') 55; 56 57# own_user_table 58# 自社ユーザーの基本情報 59CREATE TABLE own_user_table 60 (`user_id` int, `unique_name` text, `nick_name` text) 61; 62INSERT INTO own_user_table 63 (`user_id`, `unique_name`, `nick_name`) 64VALUES 65 (1, 'ichiro', '田中一郎'), 66 (2, 'jiro', '田中二郎'), 67 (3, 'saburo', '田中三郎'), 68 (4, 'shiro', '田中四郎') 69; 70 71# own_user_sub_table 72# 自社ユーザーの補足情報 73CREATE TABLE own_user_sub_table 74 (`sub_id` int, `user_id` int, `sub_key` text, `sub_val` text) 75; 76INSERT INTO own_user_sub_table 77 (`sub_id`, `user_id`, `sub_key`, `sub_val`) 78VALUES 79 (1, 1, 'studio_name', 'own'), 80 (2, 1, 'content_url', 'own/user/ichiro'), 81 (3, 2, 'studio_name', 'own'), 82 (4, 2, 'content_url', 'own/user/jiro'), 83 (5, 3, 'studio_name', 'own'), 84 (6, 3, 'content_url', 'own/user/saburo'), 85 (7, 4, 'studio_name', 'own'), 86 (8, 4, 'content_url', 'own/user/shiro') 87; 88
###試したこと
この質問自体を大きく編集してしまいましたが、いろいろ試した経緯はぐちゃぐちゃとしているので、次のコードまでたどり着いたという現状だけを掲載させて頂きます。
この実行サンプルの結果が下図で、緑が【問題➀】、赤が【問題➁】です。
SQL
1# user_id=1のfavoriteリストを取得するのが目標 2/* 3発生している問題 4【問題➀】`follow_date`と`favorite_date`が`null`となってしまうこと。 5【問題➁】「クジラの生活」の方だけ`favorite_tags`が取得できないこと。 6*/ 7select 8 # 自社ユーザーかそうでないかで取得先テーブルを分岐 9 case 10 when content_type='user' and own_user_studio_name.sub_val='own' 11 then own_user.user_id 12 else null 13 end as user_id, 14 case 15 when content_type='user' and own_user_studio_name.sub_val='own' 16 then null 17 else content.content_id 18 end as content_id, 19 case 20 when content_type='user' and own_user_studio_name.sub_val='own' 21 then own_user.nick_name 22 else content.content_text 23 end as content_text, 24 case 25 when content_type='user' and own_user_studio_name.sub_val='own' 26 then own_user.unique_name 27 else null 28 end as content_text2, 29 case 30 when content_type='user' and own_user_studio_name.sub_val='own' 31 then 'user' 32 else content_type 33 end as content_type, 34 case 35 when content_type='user' and own_user_studio_name.sub_val='own' 36 then own_user_content_url.sub_val 37 else content_content_url.sub_val 38 end as content_url, 39 case 40 when content_type='user' and own_user_studio_name.sub_val='own' 41 then own_user_studio_name.sub_val 42 else content_studio_name.sub_val 43 end as studio_name, 44 45 # アクション情報を取得 46 his_favorite.follow_date, 47 his_favorite.favorite_date, 48 action.favorite_tags 49 50from ( 51 select favorite.target_id 52 , max( 53 case when action.action_name='follow' then action.action_date end 54 ) as follow_date 55 , max( 56 case when action.action_name='favorite' then action.action_date end 57 ) as favorite_date 58 from action_table favorite 59 left join action_table action 60 on favorite.actor_id=action.target_id 61 and action.actor_id=1 62 where favorite.actor_id=1 and favorite.action_name='favorite' 63 and favorite.actor_id not in( 64 select case when target_id=1 then actor_id else target_id end 65 from action_table 66 where target_type='user' and action_name='block' and 1 in (target_id, actor_id) 67 ) 68 group by favorite.target_id 69 ) his_favorite 70 71 # アクション情報 72 left join action_table action 73 on his_favorite.target_id=action.action_id 74 75 # 自社ユーザー以外の情報 76 left join content_table content 77 on his_favorite.target_id=content.content_id 78 left join content_sub_table content_studio_name 79 on his_favorite.target_id=content_studio_name.content_id and content_studio_name.sub_key='studio_name' 80 left join content_sub_table content_content_url 81 on his_favorite.target_id=content_content_url.content_id and content_content_url.sub_key='content_url' 82 83 # 自社ユーザーの情報 84 left join own_user_table own_user 85 on his_favorite.target_id=own_user.user_id 86 left join own_user_sub_table own_user_studio_name 87 on his_favorite.target_id=own_user_studio_name.user_id and own_user_studio_name.sub_key='studio_name' 88 left join own_user_sub_table own_user_content_url 89 on his_favorite.target_id=own_user_content_url.user_id and own_user_content_url.sub_key='content_url' 90 left join own_user_sub_table own_user_content_text 91 on his_favorite.target_id=own_user_content_text.user_id and own_user_content_text.sub_key='content_text'
###補足情報(FW/ツールのバージョンなど)
phpMyAdmin(4.8.5)で、MySQL(10.0.33-MariaDB)を使っています。
SQL初心者がネットの見本などを参考に組み合わせたコードにつき、意味不明な部分などがあるかもしれませんがご容赦ください。
宜しくお願い致します。
回答2件
あなたの回答
tips
プレビュー