###前提・実現したいこと
以下2つの条件で「threadのリスト」を取得しています。
➀彼が投稿したthread
➁または彼がfollow|favorite
したthread
こうして取得された「threadのリスト」には
・his_post_date
(彼が投稿した日)
・follow_date
(彼がfollowした日)
・favorite_date
(彼がfavoriteした日)
と3つの日付があるのですが、これらをあわせて昇順でソートしたいと思っています。
###CREATE TABLE と INSERT
対象のテーブルです。3つあります。
SQL
1/* 2■テーブルの構造 3掲示板サイトのテーブルで、以下3つがあります。 4・actions_table : アクション 5・contents_table : 日本ユーザー以外の全て 6・users _table : 日本ユーザー 7*/ 8 9# actions_table 10# アクション 11CREATE TABLE actions_table 12 (action_id int, action_name text, action_date text, actor_id int, target_id int, target_type text, target_country text) 13; 14INSERT INTO actions_table 15 (action_id, action_name, action_date, actor_id, target_id, target_type, target_country) 16VALUES 17 (1, 'follow', '2020-01-00 00:00:00', 1, 2, 'user', 'jp'), 18 (2, 'follow', '2020-02-00 00:00:00', 1, 2, 'thread', 'jp'), 19 (3, 'favorite', '2020-03-00 00:00:00', 1, 3, 'thread', 'jp'), 20 (4, 'favorite', '2020-04-00 00:00:00', 2, 3, 'thread', 'jp'), 21 (5, 'block', '2020-05-00 00:00:00', 1, 3, 'user', 'jp') 22; 23 24# contents_table 25# 日本ユーザー以外の全て 26CREATE TABLE contents_table 27 (content_id int, author_id int, path text, content_date text, parent_thread_id int, content_country text, parent_content_id int, content_type text, content_text text, attach_id int, attach_type text, attach_country text) 28; 29INSERT INTO contents_table 30 (content_id, author_id, content_date, content_country, content_type, content_text ) 31VALUES 32 (1, 0, '2020-01-00 00:00:00', 'en', 'drama', '米国ドラマ' ), 33 (2, 1, '2020-02-00 00:00:00', 'jp', 'thread', '日本スレッドA' ), 34 (3, 2, '2020-03-00 00:00:00', 'jp', 'thread', '日本スレッドB' ), 35 (4, 0, '2020-04-00 00:00:00', 'en', 'user', '米国ユーザー' ) 36; 37 38# users_table 39# 日本ユーザー 40CREATE TABLE users_table 41 (user_id int, nick_name text) 42; 43INSERT INTO users_table 44 (user_id, nick_name) 45VALUES 46 (1, '田中一郎'), 47 (2, '田中二郎') 48; 49
###該当のコード
「threadのリスト」を取得するコードです。
SQL
1/* 2■当SQLの説明 3彼(user_id=1)として以下を取得している 4➀彼が投稿したthread 5➁または彼がfollow|favoriteしたthread 6*/ 7 8select 9 c.content_id 10 ,c.content_text 11 ,c.author_id 12 ,case 13 when c.author_id=1 14 then c.content_date 15 end as his_post_date 16 ,max( 17 case when a.action_name='follow' 18 then a.action_date end 19 ) as follow_date 20 ,max( 21 case when a.action_name='favorite' 22 then a.action_date end 23 ) as favorite_date 24from actions_table a 25 26# join 27left join contents_table c 28on a.target_id=c.content_id 29left join users_table u 30on a.target_id=u.user_id 31 32# ➀彼が投稿したthread 33where c.content_type='thread' 34and ( c.author_id=1 ) 35# ➁または彼がfollow|favoriteしたthread 36or ( 37 a.actor_id=1 and a.target_type='thread' 38 and a.action_name in ('favorite', 'follow') 39 and exists( 40 select 0 from actions_table 41 where target_id=a.target_id 42 and ( action_name='follow' or action_name='favorite' ) 43 ) 44) 45 46group by a.target_id
###取得のロジック
「threadのリスト」を取得するロジックです。
➀彼が投稿したthread
を取得するために、contents_table
を見て、author_id=1
かつcontent_type='thread'
のものを取得します。
続いて
➁または彼がfollow|favoriteしたthread
を取得するために、actions_table
を見て、actor_id=1
かつaction_name='follow'
かつtarget_type='thread'
のものを取得します。
以上のように「threadのリスト」はたぶん取得できたのではないかと思っています。
###試したこと
本題です。
こうして取得された「threadのリスト」には
・his_post_date
(彼が投稿した日)
・follow_date
(彼がfollowした日)
・favorite_date
(彼がfavoriteした日)
と3つの日付があるのですが、これらをあわせて昇順でソートしたいと思っています。
そこでgreatest
を使ってみたのが次のコードです。
先頭のselect
の中で3つを併せてsort_date
とし、最後の行でorder by sort_date desc
を追加したという2点の変更によって実現できる心づもりでおりました。
しかし実現できず、質問させて頂きました。
SQL
1select 2 c.content_id 3 ,c.content_text 4 ,c.author_id 5 ,case 6 when c.author_id=1 7 then c.content_date 8 end as his_post_date 9 ,max( 10 case when a.action_name='follow' 11 then a.action_date end 12 ) as follow_date 13 ,max( 14 case when a.action_name='favorite' 15 then a.action_date end 16 ) as favorite_date 17 ,greatest( his_post_date, follow_date, favorite_date ) as sort_date 18from actions_table a 19from actions_table a 20 21# join 22left join contents_table c 23on a.target_id=c.content_id 24left join users_table u 25on a.target_id=u.user_id 26 27# ➀彼が投稿したthread 28where c.content_type='thread' 29and ( c.author_id=1 ) 30# ➁または彼がfollow|favoriteしたthread 31or ( 32 a.actor_id=1 and a.target_type='thread' 33 and a.action_name in ('favorite', 'follow') 34 and exists( 35 select 0 from actions_table 36 where target_id=a.target_id 37 and ( action_name='follow' or action_name='favorite' ) 38 ) 39) 40 41group by a.target_id 42order by sort_date desc 43
###補足情報(FW/ツールのバージョンなど)
phpMyAdmin(4.8.5)で、MySQL(10.0.33-MariaDB)を使っています。
もしかしたらそもそも取得のロジックの考え方が間違っているのかもしれませんが、実現したいことは**『➀➁の条件で「threadのリスト」を取得し、3つの日付でソートする』**ということで変わりありません。
実現のためのお力添え頂けましたら幸甚に存じます。
宜しくお願い致します。
###ソート方法について追記
3つの日付の中で、最大値を基準としたソートを考えています。
例えば現状の「threadのリスト」(該当のコードのSQL fiddleで取得されるもの)では
「日本スレッドA、日本スレッドB」の順で取得されていますが、これを
「日本スレッドB、日本スレッドA」の順にしたいということです。
「日本スレッドA」は最大値が「2020-02-00 00:00:00」であるのに対して、
「日本スレッドB」は最大値が「2020-03-00 00:00:00」だからです。
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/03/02 02:18 編集
2020/03/01 13:49
2020/03/02 01:31 編集
2020/03/02 02:01 編集
2020/03/02 02:00
2020/03/02 02:00
2020/03/02 02:16 編集
2020/03/02 02:24
2020/03/02 02:25
2020/03/02 03:19 編集
2020/03/02 03:17 編集
2020/03/02 03:25 編集
2020/03/02 05:09
2020/03/02 05:22 編集
2020/03/02 10:36