質問編集履歴
11
SQLfiddleを修正
title
CHANGED
File without changes
|
body
CHANGED
@@ -7,7 +7,7 @@
|
|
7
7
|
|
8
8
|
`on ●●➀`と`on ●●➁`という連結条件が違うので2回書かないといけないと思っていますが、重複させずにすっきりさせる方法はありますか?
|
9
9
|
|
10
|
-
[下記のコードを実行する(SQLfiddle)](http://sqlfiddle.com/#!9/b0a45e/
|
10
|
+
[下記のコードを実行する(SQLfiddle)](http://sqlfiddle.com/#!9/b0a45e/10)
|
11
11
|
```SQL
|
12
12
|
select *
|
13
13
|
from (
|
10
SQLfiddleを修正
title
CHANGED
File without changes
|
body
CHANGED
@@ -7,7 +7,7 @@
|
|
7
7
|
|
8
8
|
`on ●●➀`と`on ●●➁`という連結条件が違うので2回書かないといけないと思っていますが、重複させずにすっきりさせる方法はありますか?
|
9
9
|
|
10
|
-
[下記のコードを実行する(SQLfiddle)](http://sqlfiddle.com/#!9/b0a45e/
|
10
|
+
[下記のコードを実行する(SQLfiddle)](http://sqlfiddle.com/#!9/b0a45e/9)
|
11
11
|
```SQL
|
12
12
|
select *
|
13
13
|
from (
|
9
SQLfiddleを修正
title
CHANGED
File without changes
|
body
CHANGED
@@ -7,7 +7,7 @@
|
|
7
7
|
|
8
8
|
`on ●●➀`と`on ●●➁`という連結条件が違うので2回書かないといけないと思っていますが、重複させずにすっきりさせる方法はありますか?
|
9
9
|
|
10
|
-
[下記のコードを実行する(SQLfiddle)](http://sqlfiddle.com/#!9/b0a45e/
|
10
|
+
[下記のコードを実行する(SQLfiddle)](http://sqlfiddle.com/#!9/b0a45e/8)
|
11
11
|
```SQL
|
12
12
|
select *
|
13
13
|
from (
|
8
SQLfiddleを追記
title
CHANGED
File without changes
|
body
CHANGED
@@ -7,6 +7,7 @@
|
|
7
7
|
|
8
8
|
`on ●●➀`と`on ●●➁`という連結条件が違うので2回書かないといけないと思っていますが、重複させずにすっきりさせる方法はありますか?
|
9
9
|
|
10
|
+
[下記のコードを実行する(SQLfiddle)](http://sqlfiddle.com/#!9/b0a45e/4)
|
10
11
|
```SQL
|
11
12
|
select *
|
12
13
|
from (
|
7
自己解決したため編集
title
CHANGED
@@ -1,1 +1,1 @@
|
|
1
|
-
|
1
|
+
JOINのONが違うとき、同じSELECTを2回書かないといけませんか?
|
body
CHANGED
@@ -1,2 +1,41 @@
|
|
1
|
-
|
1
|
+
※自己解決し問題点が明確になったため、その本質に不要な細部を●●と抽象した内容で以下編集致しました。
|
2
|
+
|
2
|
-
|
3
|
+
コメントをくださったお二方、どうもありがとうございました。
|
4
|
+
|
5
|
+
###質問
|
6
|
+
以下`#join➀`と`#join➁`について、`left outer join ( この中 )`に同じ処理を重複して書いてしまい、冗長に感じています。
|
7
|
+
|
8
|
+
`on ●●➀`と`on ●●➁`という連結条件が違うので2回書かないといけないと思っていますが、重複させずにすっきりさせる方法はありますか?
|
9
|
+
|
10
|
+
```SQL
|
11
|
+
select *
|
12
|
+
from (
|
13
|
+
select ●●
|
14
|
+
from ●●
|
15
|
+
|
16
|
+
left join ●●
|
17
|
+
on ●●
|
18
|
+
left join ●●
|
19
|
+
on ●●
|
20
|
+
left join ●●
|
21
|
+
on ●●
|
22
|
+
|
23
|
+
# join➀
|
24
|
+
left outer join (
|
25
|
+
select ●●
|
26
|
+
from ●●
|
27
|
+
where ●●
|
28
|
+
) as ●●
|
29
|
+
on ●●➀
|
30
|
+
|
31
|
+
where ●●
|
32
|
+
) as ●●
|
33
|
+
|
34
|
+
# join➁
|
35
|
+
left outer join (
|
36
|
+
select ●●
|
37
|
+
from ●●
|
38
|
+
where ●●
|
39
|
+
) as ●●
|
40
|
+
on ●●➁
|
41
|
+
```
|
6
編集中
title
CHANGED
@@ -1,1 +1,1 @@
|
|
1
|
-
|
1
|
+
こちらの質問は現在編集中です
|
body
CHANGED
@@ -1,253 +1,2 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
`path`のカラムの値は重複しないので必ず取得は1件です。
|
4
|
-
|
5
|
-
取得された「対象」には、「対象の添付データ」もありまして、それぞれに「アクション日」があります。
|
6
|
-
|
7
|
-
つまり、「対象へのアクション日」や「対象の添付データへのアクション日」という具合です。
|
8
|
-
|
9
|
-
###質問
|
10
|
-
上のようにそれぞれの「アクション日」があるために`JOIN`させる`ON`が2通りあるのですが、その2通りのために`jp_actions_table`テーブルに2回同じ処理をしていることに違和感を覚えています。これを改善したいです。
|
11
|
-
|
12
|
-
|
13
|
-
図でいうと緑の部分で、SQLfiddleでいうと50行目と80行目です。
|
14
|
-

|
15
|
-
|
16
|
-
得たい結果は上図レコードで、`user_id=1`さん(彼)が`path='/7'`のページ(対象)を閲覧している仮定の結果です。
|
17
|
-
|
18
|
-
この結果は1~5のロジックで得られ、2と5で`jp_actions_table`に同じ処理をしている下記ソースコードに冗長さを覚えます。
|
19
|
-
|
20
|
-
1.「対象」を取得(図のオレンジ)
|
21
|
-
`jp_contents_table`から`path='/7'`のレコードを1件取得
|
22
|
-
|
23
|
-
2.「対象へのアクション日」を取得(図の緑)
|
24
|
-
彼が「対象」を`follow`した日が欲しい。そこで`jp_actions_table`から`action_date`を取得。そして`follow`対象である`target_id`と、「対象」の`content_id`で連結。
|
25
|
-
|
26
|
-
3.「対象の投稿者」を連結(図の青)
|
27
|
-
誰が対象を投稿したのかが欲しい。そこで`jp_contents_table`の`author_id`と、`jp_users_table`の`user_id`で連結。
|
28
|
-
|
29
|
-
4.「対象の添付データ」を連結(図の紫)
|
30
|
-
対象に添付データがあれば欲しい。そこで`jp_contents_table`の`attach_id`と、`jp_users_table`または`jp_content_table`で連結。
|
31
|
-
|
32
|
-
5.「対象の添付データへのアクション日」を連結(図の緑)
|
33
|
-
彼が「対象の添付データ」を`follow`した日が欲しい。そこで`jp_actions_table`から`action_date`を取得。そして`follow`対象である`target_id`と、「対象」の`attach_id`で連結。
|
34
|
-
|
35
|
-
|
36
|
-
###ソースコード
|
37
|
-
こちらが1~5のソースコードです。
|
38
|
-
|
39
|
-
リンク先SQLfiddleにある
|
40
|
-
50行目の`# 「対象へのアクション日」をjoin`
|
41
|
-
89行目の`# 「対象の添付データへのアクション日」をjoin`
|
42
|
-
が`jp_actions_table` テーブルに同じ処理を2回している部分です。
|
43
|
-
|
44
|
-
50行目も89行目も、`left outer join ( この中 )`は同じなのに、`JOIN`させる`ON`が違うだけという理由で2回書いているのですが、スッキリさせられませんでしょうか。
|
45
|
-
|
46
|
-
[下記のソースコードを実行する(SQLfiddle)](http://sqlfiddle.com/#!9/062788/3)
|
47
|
-
```SQL
|
48
|
-
/*
|
49
|
-
■テーブルの構造
|
50
|
-
掲示板サイトのテーブルで、以下4つがあります。
|
51
|
-
・jp_actions_table : アクション
|
52
|
-
・jp_contents_table : コンテンツ
|
53
|
-
・jp_users _table : ユーザー
|
54
|
-
*/
|
55
|
-
|
56
|
-
# jp_actions
|
57
|
-
# アクションのテーブル
|
58
|
-
CREATE TABLE jp_actions_table
|
59
|
-
(action_id int, action_name text, action_date text, actor_id int, target_id int, target_type text, target_country_code text)
|
60
|
-
;
|
61
|
-
INSERT INTO jp_actions_table
|
62
|
-
(action_id, action_name, action_date, actor_id, target_id, target_type, target_country_code)
|
63
|
-
VALUES
|
64
|
-
(1, 'follow', '2020-01-00 00:00:00', 1, 2, 'user', 'jp'),
|
65
|
-
(2, 'follow', '2020-02-00 00:00:00', 1, 2, 'tag', ''),
|
66
|
-
(3, 'favorite', '2020-03-00 00:00:00', 1, 3, 'user', 'jp'),
|
67
|
-
(4, 'favorite', '2020-04-00 00:00:00', 2, 5, 'user', 'jp'),
|
68
|
-
(5, 'favorite', '2020-05-00 00:00:00', 1, 7, 'comment', 'jp'),
|
69
|
-
(6, 'block', '2020-06-00 08:00:00', 1, 3, 'user', 'jp'),
|
70
|
-
(7, 'favorite', '2020-07-00 07:00:00', 1, 5, 'user', 'jp'),
|
71
|
-
(8, 'favorite', '2020-08-00 08:00:00', 1, 5, 'movie', 'en'),
|
72
|
-
(9, 'favorite', '2020-09-00 09:00:00', 1, 3, 'user', 'ko'),
|
73
|
-
(10, 'favorite', '2020-10-00 10:00:00', 1, 3, 'thread', 'jp'),
|
74
|
-
(11, 'follow', '2020-11-00 11:00:00', 1, 9, 'thread', 'jp')
|
75
|
-
;
|
76
|
-
|
77
|
-
# jp_contents
|
78
|
-
# jpのコンテンツのテーブル
|
79
|
-
CREATE TABLE jp_contents_table
|
80
|
-
(content_id int, author_id int, path text, content_date text, parent_thread_id int, country_code text, parent_content_id int, content_type text, content_text text, attach_id int, attach_type text, attach_country_code text)
|
81
|
-
;
|
82
|
-
INSERT INTO jp_contents_table
|
83
|
-
(content_id, author_id, path, content_date, parent_thread_id, parent_content_id, country_code, content_type, content_text, attach_id, attach_type, attach_country_code)
|
84
|
-
VALUES
|
85
|
-
(1, 0, '/1', '2020-01-00 00:00:00', 0, 0, 'en', 'drama', 'Mr.ROBOT', 0, '', ''),
|
86
|
-
(2, 3, '/2', '2020-02-00 00:00:00', 0, 0, 'jp', 'thread', '韓国の映画について語るスレ', 0, '', ''),
|
87
|
-
(3, 3, '/3', '2020-03-00 00:00:00', 0, 0, 'jp', 'thread', '米国の映画について語るスレ', 0, '', ''),
|
88
|
-
(4, 3, '/4', '2020-04-00 00:00:00', 3, 0, 'jp', 'comment', '米国のお勧め映画は何ですか?', 0, '', ''),
|
89
|
-
(5, 0, '/5', '2020-05-00 00:00:00', 0, 0, 'ko', 'manga', '지안', 0, '', ''),
|
90
|
-
(6, 1, '/6', '2020-06-00 00:00:00', 3, 4, 'jp', 'reply', '米国のMr.ROBOTを添付します。', 4, 'drama', 'en'),
|
91
|
-
(7, 4, '/7', '2020-07-00 00:00:00', 2, 0, 'jp', 'comment', '韓国の지안さんを添付します。', 3, 'user', 'ko'),
|
92
|
-
(8, 1, '/8', '2020-08-00 00:00:00', 3, 6, 'jp', 'reply', '面白そうですね。', 0, '', ''),
|
93
|
-
(9, 3, '/9', '2020-09-00 00:00:00', 3, 6, 'jp', 'reply', '良いですね。', 0, '', ''),
|
94
|
-
(10, 2, '/10', '2020-10-00 00:00:00', 3, 9, 'jp', 'reply', 'ええ、とても良いですよ。', 0, '', ''),
|
95
|
-
(11, 3, '/11', '2020-11-00 00:00:00', 0, 0, 'jp', 'thread', '日本の田中家について語るスレ', 0, '', ''),
|
96
|
-
(12, 1, '/12', '2020-12-00 00:00:00', 11, 0, 'jp', 'comment', '日本の三郎さんを添付します。', 3, 'user', 'jp'),
|
97
|
-
(13, 2, '/13', '2020-13-00 00:00:00', 2, 0, 'jp', 'comment', '米国の映画スレを添付します', 9, 'thread', 'jp'),
|
98
|
-
(14, 0, '/14', '2020-14-00 00:00:00', 0, 0, 'en', 'user', 'smith', 0, '', ''),
|
99
|
-
(15, 0, '/15', '2020-15-00 00:00:00', 0, 0, 'zh', 'manga', '砂輿海之歌', 0, '', ''),
|
100
|
-
(16, 0, '/16', '2020-16-00 00:00:00', 0, 0, 'en', 'movie', 'Avator', 0, '', ''),
|
101
|
-
(17, 0, '/17', '2020-17-00 00:00:00', 0, 0, 'ru', 'movie', 'Хардкор', 0, '', ''),
|
102
|
-
(18, 0, '/18', '2020-18-00 00:00:00', 0, 0, 'zh', 'drama', '大秦帝国', 0, '', '')
|
103
|
-
;
|
104
|
-
# jp_users
|
105
|
-
# ユーザーのテーブル
|
106
|
-
CREATE TABLE jp_users_table
|
107
|
-
(user_id int, unique_name text, nick_name text)
|
108
|
-
;
|
109
|
-
INSERT INTO jp_users_table
|
110
|
-
(user_id, unique_name, nick_name)
|
111
|
-
VALUES
|
112
|
-
(1, 'ichiro', '田中一郎'),
|
113
|
-
(2, 'jiro', '田中二郎'),
|
114
|
-
(3, 'saburo', '田中三郎'),
|
115
|
-
(4, 'shiro', '田中四郎'),
|
116
|
-
(5, 'goro', '山田五郎'),
|
117
|
-
(6, 'rokuro', '山田六郎'),
|
118
|
-
(7, 'nanaro', '山田七郎')
|
119
|
-
;
|
120
|
-
|
121
|
-
/*
|
122
|
-
■当SQLの概要
|
123
|
-
jp_contents_table から path='/7' を「対象」として取得します。
|
124
|
-
そして
|
125
|
-
「対象へのアクション日」
|
126
|
-
「対象の投稿者」
|
127
|
-
「対象の添付データ」
|
128
|
-
「対象の添付データへのアクション日」
|
129
|
-
も併せて取得します
|
130
|
-
*/
|
131
|
-
select *
|
132
|
-
from (
|
133
|
-
select
|
134
|
-
# 「対象」
|
135
|
-
t1.content_id
|
136
|
-
,t1.author_id
|
137
|
-
,t1.path
|
138
|
-
,t1.content_date
|
139
|
-
,t1.parent_thread_id
|
140
|
-
,t1.parent_content_id
|
141
|
-
,t1.content_type
|
142
|
-
,t1.content_text
|
143
|
-
,t1.attach_id
|
144
|
-
,t1.attach_type
|
145
|
-
,t1.attach_country_code
|
146
|
-
# 「対象へのアクション日」
|
147
|
-
,base_action_record.follow_date
|
148
|
-
,base_action_record.favorite_date
|
149
|
-
,base_action_record.block_date
|
150
|
-
# 「対象の投稿者」
|
151
|
-
,case when t1.attach_country_code='jp' and t1.attach_type='user'
|
152
|
-
then null else jp_a.nick_name end as author_nickname
|
153
|
-
# 「対象の添付データ」
|
154
|
-
,case when t1.attach_country_code='jp' and t1.attach_type='user'
|
155
|
-
then jp_u.nick_name else null end as attached_nick_name
|
156
|
-
,case when t1.attach_country_code='jp' and t1.attach_type='user'
|
157
|
-
then null else jp_c.content_text end as attached_content_text
|
158
|
-
from jp_contents_table t1
|
159
|
-
|
160
|
-
# 「対象の投稿者」をjoin
|
161
|
-
left join jp_users_table jp_a
|
162
|
-
on t1.author_id=jp_a.user_id
|
163
|
-
|
164
|
-
# 「対象の添付データ」をjoin
|
165
|
-
left join jp_users_table jp_u
|
166
|
-
on t1.attach_id=jp_u.user_id
|
167
|
-
left join jp_contents_table jp_c
|
168
|
-
on t1.attach_id=jp_c.content_id
|
169
|
-
|
170
|
-
# 「対象へのアクション日」をjoin
|
171
|
-
left outer join (
|
172
|
-
select jp_actions.target_id
|
173
|
-
,jp_actions.target_type
|
174
|
-
,jp_actions.target_country_code
|
175
|
-
,max( case
|
176
|
-
when jp_actions.action_name='follow'
|
177
|
-
then jp_actions.action_date
|
178
|
-
end ) as follow_date
|
179
|
-
,max( case
|
180
|
-
when jp_actions.action_name='favorite'
|
181
|
-
then jp_actions.action_date
|
182
|
-
end ) as favorite_date
|
183
|
-
,max( case
|
184
|
-
when jp_actions.action_name='block'
|
185
|
-
then jp_actions.action_date
|
186
|
-
end ) as block_date
|
187
|
-
from jp_actions_table jp_actions
|
188
|
-
# 実行者1のアクション
|
189
|
-
where jp_actions.actor_id=1
|
190
|
-
and jp_actions.action_name in ('favorite','follow','block')
|
191
|
-
and exists(
|
192
|
-
select 0 from jp_actions_table
|
193
|
-
where target_id=jp_actions.target_id
|
194
|
-
and action_name in ('favorite','follow','block')
|
195
|
-
)
|
196
|
-
|
197
|
-
group by jp_actions.target_id, jp_actions.target_type, jp_actions.target_country_code
|
198
|
-
|
199
|
-
) as base_action_record
|
200
|
-
|
201
|
-
on base_action_record.target_id=t1.content_id
|
202
|
-
and base_action_record.target_type=t1.content_type
|
203
|
-
and base_action_record.target_country_code=t1.country_code
|
204
|
-
|
205
|
-
# 取得をpathで指定(country_codeとcontent_typeにindexあり)
|
206
|
-
where t1.path='/7' and t1.country_code='jp' and t1.content_type='comment'
|
207
|
-
) as base_record
|
208
|
-
|
209
|
-
# 「対象の添付データへのアクション日」をjoin
|
210
|
-
left outer join (
|
211
|
-
select jp_actions.target_id
|
212
|
-
,jp_actions.target_type
|
213
|
-
,jp_actions.target_country_code
|
214
|
-
,max( case
|
215
|
-
when jp_actions.action_name='follow'
|
216
|
-
then jp_actions.action_date
|
217
|
-
end ) as attached_follow_date
|
218
|
-
,max( case
|
219
|
-
when jp_actions.action_name='favorite'
|
220
|
-
then jp_actions.action_date
|
221
|
-
end ) as attached_favorite_date
|
222
|
-
,max( case
|
223
|
-
when jp_actions.action_name='block'
|
224
|
-
then jp_actions.action_date
|
225
|
-
end ) as attached_block_date
|
226
|
-
from jp_actions_table jp_actions
|
227
|
-
# 実行者1のアクション
|
228
|
-
where jp_actions.actor_id=1
|
229
|
-
and jp_actions.action_name in ('favorite','follow','block')
|
230
|
-
and exists(
|
231
|
-
select 0 from jp_actions_table
|
232
|
-
where target_id=jp_actions.target_id
|
233
|
-
and action_name in ('favorite','follow','block')
|
234
|
-
)
|
235
|
-
|
236
|
-
group by jp_actions.target_id, jp_actions.target_type, jp_actions.target_country_code
|
237
|
-
|
238
|
-
) as attach_action_record
|
239
|
-
|
240
|
-
on attach_action_record.target_id=base_record.attach_id
|
241
|
-
and attach_action_record.target_type=base_record.attach_type
|
242
|
-
and attach_action_record.target_country_code=base_record.attach_country_code
|
243
|
-
|
244
|
-
|
245
|
-
```
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
###補足情報(FW/ツールのバージョンなど)
|
250
|
-
phpMyAdmin(4.8.5)で、MySQL(10.0.33-MariaDB)を使っています。
|
251
|
-
|
252
|
-
※編集(2020-02-18)
|
253
|
-
質問の項目に「どういうロジック」を1~5のように追記させて頂きました。その際に文字数制限がきてしまったため、試したことの項目を削除致しました。
|
1
|
+
質問が大変わかりにくかったため要点を絞るべく編集中です。
|
2
|
+
ご迷惑おかけして申し訳ございません。
|
5
誤字などの訂正
title
CHANGED
@@ -1,1 +1,1 @@
|
|
1
|
-
SQLで、JOINのONが異なる場合、同じ
|
1
|
+
SQLで、JOINのONが異なる場合、JOINの内容が同じでも2回書かないといけませんか?
|
body
CHANGED
@@ -7,11 +7,13 @@
|
|
7
7
|
つまり、「対象へのアクション日」や「対象の添付データへのアクション日」という具合です。
|
8
8
|
|
9
9
|
###質問
|
10
|
-
上のようにそれぞれの「アクション日」があるために`JOIN`させる`ON`が2通りあるのですが、その2通りのために`jp_actions_table`テーブルに2回同じ処理をしていること
|
10
|
+
上のようにそれぞれの「アクション日」があるために`JOIN`させる`ON`が2通りあるのですが、その2通りのために`jp_actions_table`テーブルに2回同じ処理をしていることに違和感を覚えています。これを改善したいです。
|
11
11
|
|
12
|
+
|
13
|
+
図でいうと緑の部分で、SQLfiddleでいうと50行目と80行目です。
|
12
14
|

|
13
15
|
|
14
|
-
得たい結果は上図レコードで、`user_id=1`さん(彼)が`path='/7'`のページ(対象)を閲覧している
|
16
|
+
得たい結果は上図レコードで、`user_id=1`さん(彼)が`path='/7'`のページ(対象)を閲覧している仮定の結果です。
|
15
17
|
|
16
18
|
この結果は1~5のロジックで得られ、2と5で`jp_actions_table`に同じ処理をしている下記ソースコードに冗長さを覚えます。
|
17
19
|
|
@@ -21,21 +23,19 @@
|
|
21
23
|
2.「対象へのアクション日」を取得(図の緑)
|
22
24
|
彼が「対象」を`follow`した日が欲しい。そこで`jp_actions_table`から`action_date`を取得。そして`follow`対象である`target_id`と、「対象」の`content_id`で連結。
|
23
25
|
|
24
|
-
3.「対象の投稿者」を
|
26
|
+
3.「対象の投稿者」を連結(図の青)
|
25
27
|
誰が対象を投稿したのかが欲しい。そこで`jp_contents_table`の`author_id`と、`jp_users_table`の`user_id`で連結。
|
26
28
|
|
27
|
-
4.「対象の添付データ」を
|
29
|
+
4.「対象の添付データ」を連結(図の紫)
|
28
30
|
対象に添付データがあれば欲しい。そこで`jp_contents_table`の`attach_id`と、`jp_users_table`または`jp_content_table`で連結。
|
29
31
|
|
30
|
-
5.「対象の添付データへのアクション日」(図の緑)
|
32
|
+
5.「対象の添付データへのアクション日」を連結(図の緑)
|
31
|
-
彼が「対象の添付データ」を`follow`した日が欲しい。そこで`jp_actions_table`から`action_date`を取得。そして`follow`対象である`target_id`と、「対象
|
33
|
+
彼が「対象の添付データ」を`follow`した日が欲しい。そこで`jp_actions_table`から`action_date`を取得。そして`follow`対象である`target_id`と、「対象」の`attach_id`で連結。
|
32
34
|
|
33
35
|
|
34
36
|
###ソースコード
|
35
|
-
こちらが
|
37
|
+
こちらが1~5のソースコードです。
|
36
38
|
|
37
|
-
`jp_contents_table` テーブルから`path`のカラムが`/7`であるレコード(対象)を1件取得して、上図のように連結しています。
|
38
|
-
|
39
39
|
リンク先SQLfiddleにある
|
40
40
|
50行目の`# 「対象へのアクション日」をjoin`
|
41
41
|
89行目の`# 「対象の添付データへのアクション日」をjoin`
|
@@ -43,7 +43,7 @@
|
|
43
43
|
|
44
44
|
50行目も89行目も、`left outer join ( この中 )`は同じなのに、`JOIN`させる`ON`が違うだけという理由で2回書いているのですが、スッキリさせられませんでしょうか。
|
45
45
|
|
46
|
-
[下記のソースコードを実行する](http://sqlfiddle.com/#!9/062788/3)
|
46
|
+
[下記のソースコードを実行する(SQLfiddle)](http://sqlfiddle.com/#!9/062788/3)
|
47
47
|
```SQL
|
48
48
|
/*
|
49
49
|
■テーブルの構造
|
4
誤字などの訂正
title
CHANGED
File without changes
|
body
CHANGED
@@ -1,25 +1,25 @@
|
|
1
1
|
###前提
|
2
|
-
`jp_contents_table`
|
2
|
+
`jp_contents_table`テーブルから`path`のカラムが`/7`であるレコード(対象)を1件取得するSQLを書いています。
|
3
3
|
`path`のカラムの値は重複しないので必ず取得は1件です。
|
4
4
|
|
5
|
-
取得された「対象」には、「添付データ」もありまして、それぞれに「アクション日」があります。
|
5
|
+
取得された「対象」には、「対象の添付データ」もありまして、それぞれに「アクション日」があります。
|
6
6
|
|
7
|
-
つまり、「対象
|
7
|
+
つまり、「対象へのアクション日」や「対象の添付データへのアクション日」という具合です。
|
8
8
|
|
9
9
|
###質問
|
10
|
-
上のようにそれぞれの「アクション日」があるために`JOIN`させる`ON`が2通りあるのですが、その2通りのために`jp_actions_table`
|
10
|
+
上のようにそれぞれの「アクション日」があるために`JOIN`させる`ON`が2通りあるのですが、その2通りのために`jp_actions_table`テーブルに2回同じ処理をしていること(図の緑)に違和感を覚えています。これを改善したいです。
|
11
11
|
|
12
12
|

|
13
13
|
|
14
|
-
得たい結果は上図で、
|
14
|
+
得たい結果は上図レコードで、`user_id=1`さん(彼)が`path='/7'`のページ(対象)を閲覧している設定の結果です。
|
15
15
|
|
16
|
-
この
|
16
|
+
この結果は1~5のロジックで得られ、2と5で`jp_actions_table`に同じ処理をしている下記ソースコードに冗長さを覚えます。
|
17
17
|
|
18
18
|
1.「対象」を取得(図のオレンジ)
|
19
19
|
`jp_contents_table`から`path='/7'`のレコードを1件取得
|
20
20
|
|
21
21
|
2.「対象へのアクション日」を取得(図の緑)
|
22
|
-
彼が「対象」を`follow`した日が欲しい。そこで`jp_actions_table`から`action_date`を取得。そして`follow`対象である`target_id`と、「対象」の`content_id`で連結。
|
22
|
+
彼が「対象」を`follow`した日が欲しい。そこで`jp_actions_table`から`action_date`を取得。そして`follow`対象である`target_id`と、「対象」の`content_id`で連結。
|
23
23
|
|
24
24
|
3.「対象の投稿者」を取得(図の青)
|
25
25
|
誰が対象を投稿したのかが欲しい。そこで`jp_contents_table`の`author_id`と、`jp_users_table`の`user_id`で連結。
|
@@ -28,7 +28,7 @@
|
|
28
28
|
対象に添付データがあれば欲しい。そこで`jp_contents_table`の`attach_id`と、`jp_users_table`または`jp_content_table`で連結。
|
29
29
|
|
30
30
|
5.「対象の添付データへのアクション日」(図の緑)
|
31
|
-
彼が「対象の添付データ」を`follow`した日が欲しい。そこで`jp_actions_table`から`action_date`を取得。そして`follow`対象である`target_id`と、「対象の添付データ」の`content_id`で連結。
|
31
|
+
彼が「対象の添付データ」を`follow`した日が欲しい。そこで`jp_actions_table`から`action_date`を取得。そして`follow`対象である`target_id`と、「対象の添付データ」の`content_id`で連結。
|
32
32
|
|
33
33
|
|
34
34
|
###ソースコード
|
@@ -36,11 +36,12 @@
|
|
36
36
|
|
37
37
|
`jp_contents_table` テーブルから`path`のカラムが`/7`であるレコード(対象)を1件取得して、上図のように連結しています。
|
38
38
|
|
39
|
-
リンク先
|
39
|
+
リンク先SQLfiddleにある
|
40
40
|
50行目の`# 「対象へのアクション日」をjoin`
|
41
41
|
89行目の`# 「対象の添付データへのアクション日」をjoin`
|
42
|
-
が`jp_actions_table` テーブルを2回
|
42
|
+
が`jp_actions_table` テーブルに同じ処理を2回している部分です。
|
43
43
|
|
44
|
+
50行目も89行目も、`left outer join ( この中 )`は同じなのに、`JOIN`させる`ON`が違うだけという理由で2回書いているのですが、スッキリさせられませんでしょうか。
|
44
45
|
|
45
46
|
[下記のソースコードを実行する](http://sqlfiddle.com/#!9/062788/3)
|
46
47
|
```SQL
|
3
誤字などを修正
title
CHANGED
File without changes
|
body
CHANGED
@@ -13,7 +13,7 @@
|
|
13
13
|
|
14
14
|
得たい結果は上図で、これは`user_id=1`さん(彼)が、`path='/7'`のページ(対象)を閲覧している設定における取得結果です。
|
15
15
|
|
16
|
-
この取得が以下1~5のロジックでして、2と5で同じ`jp_actions_table`が呼ばれ
|
16
|
+
この取得が以下1~5のロジックでして、2と5で同じ`jp_actions_table`が呼ばれるのですた、下記ソースコードに冗長さを覚えます。
|
17
17
|
|
18
18
|
1.「対象」を取得(図のオレンジ)
|
19
19
|
`jp_contents_table`から`path='/7'`のレコードを1件取得
|
@@ -22,10 +22,10 @@
|
|
22
22
|
彼が「対象」を`follow`した日が欲しい。そこで`jp_actions_table`から`action_date`を取得。そして`follow`対象である`target_id`と、「対象」の`content_id`で連結。(SQLfidleの50行目がこれです)
|
23
23
|
|
24
24
|
3.「対象の投稿者」を取得(図の青)
|
25
|
-
誰が対象を投稿したのかが欲しい。そこで`
|
25
|
+
誰が対象を投稿したのかが欲しい。そこで`jp_contents_table`の`author_id`と、`jp_users_table`の`user_id`で連結。
|
26
26
|
|
27
27
|
4.「対象の添付データ」を取得(図の紫)
|
28
|
-
対象に添付データがあれば欲しいそこで`
|
28
|
+
対象に添付データがあれば欲しい。そこで`jp_contents_table`の`attach_id`と、`jp_users_table`または`jp_content_table`で連結。
|
29
29
|
|
30
30
|
5.「対象の添付データへのアクション日」(図の緑)
|
31
31
|
彼が「対象の添付データ」を`follow`した日が欲しい。そこで`jp_actions_table`から`action_date`を取得。そして`follow`対象である`target_id`と、「対象の添付データ」の`content_id`で連結。(SQLfidleの89行目がこれです)
|
@@ -244,5 +244,9 @@
|
|
244
244
|
```
|
245
245
|
|
246
246
|
|
247
|
+
|
247
248
|
###補足情報(FW/ツールのバージョンなど)
|
248
|
-
phpMyAdmin(4.8.5)で、MySQL(10.0.33-MariaDB)を使っています。
|
249
|
+
phpMyAdmin(4.8.5)で、MySQL(10.0.33-MariaDB)を使っています。
|
250
|
+
|
251
|
+
※編集(2020-02-18)
|
252
|
+
質問の項目に「どういうロジック」を1~5のように追記させて頂きました。その際に文字数制限がきてしまったため、試したことの項目を削除致しました。
|
2
どういうロジックでどういう結果を得たいかを追記させて頂きました。
title
CHANGED
File without changes
|
body
CHANGED
@@ -7,21 +7,30 @@
|
|
7
7
|
つまり、「対象」への「アクション日」や、「添付データ」への「アクション日」という具合です。
|
8
8
|
|
9
9
|
###質問
|
10
|
-
上のようにそれぞれの「アクション日」があるために`JOIN`させる`ON`が2通りあるのですが、その2通りのために`
|
10
|
+
上のようにそれぞれの「アクション日」があるために`JOIN`させる`ON`が2通りあるのですが、その2通りのために`jp_actions_table` テーブルを2回呼んでいること(図の緑)にやや違和感を覚えています。これを改善したいです。
|
11
11
|
|
12
|
-
具体的には後述するソースコードで
|
13
|
-
「対象」
|
14
|
-
「対象へのアクション日」
|
15
|
-
「対象の投稿者」
|
16
|
-
「対象の添付データ」
|
17
|
-
「対象の添付データへのアクション日」
|
18
|
-
|
12
|
+

|
19
13
|
|
20
|
-
|
14
|
+
得たい結果は上図で、これは`user_id=1`さん(彼)が、`path='/7'`のページ(対象)を閲覧している設定における取得結果です。
|
21
15
|
|
22
|
-
|
16
|
+
この取得が以下1~5のロジックでして、2と5で同じ`jp_actions_table`が呼ばれ冗長に思えるのです。
|
23
17
|
|
18
|
+
1.「対象」を取得(図のオレンジ)
|
19
|
+
`jp_contents_table`から`path='/7'`のレコードを1件取得
|
24
20
|
|
21
|
+
2.「対象へのアクション日」を取得(図の緑)
|
22
|
+
彼が「対象」を`follow`した日が欲しい。そこで`jp_actions_table`から`action_date`を取得。そして`follow`対象である`target_id`と、「対象」の`content_id`で連結。(SQLfidleの50行目がこれです)
|
23
|
+
|
24
|
+
3.「対象の投稿者」を取得(図の青)
|
25
|
+
誰が対象を投稿したのかが欲しい。そこで`jp_content_table`の`author_id`と、`jp_users`の`user_id`で連結。
|
26
|
+
|
27
|
+
4.「対象の添付データ」を取得(図の紫)
|
28
|
+
対象に添付データがあれば欲しいそこで`jp_content_table`の`attach_id`と、`jp_users`または`jp_content_table`で連結。
|
29
|
+
|
30
|
+
5.「対象の添付データへのアクション日」(図の緑)
|
31
|
+
彼が「対象の添付データ」を`follow`した日が欲しい。そこで`jp_actions_table`から`action_date`を取得。そして`follow`対象である`target_id`と、「対象の添付データ」の`content_id`で連結。(SQLfidleの89行目がこれです)
|
32
|
+
|
33
|
+
|
25
34
|
###ソースコード
|
26
35
|
こちらがその冗長さを覚えるというソースコードです。
|
27
36
|
|
@@ -30,7 +39,7 @@
|
|
30
39
|
リンク先SQL fiddleにある
|
31
40
|
50行目の`# 「対象へのアクション日」をjoin`
|
32
41
|
89行目の`# 「対象の添付データへのアクション日」をjoin`
|
33
|
-
が`
|
42
|
+
が`jp_actions_table` テーブルを2回呼んでいるという処理になります。
|
34
43
|
|
35
44
|
|
36
45
|
[下記のソースコードを実行する](http://sqlfiddle.com/#!9/062788/3)
|
@@ -233,23 +242,7 @@
|
|
233
242
|
|
234
243
|
|
235
244
|
```
|
236
|
-
###試したこと
|
237
245
|
|
238
|
-
「対象」との連結が81行目のこちらで、
|
239
|
-
`on base_action_record.target_id=t1.content_id`
|
240
|
-
そして「対象の添付データ」との連結が123行目のこちらになるので、
|
241
|
-
`on attach_action_record.target_id=base_record.attach_id`
|
242
|
-
これらの条件をまとめてかければと思いました。
|
243
246
|
|
244
|
-
しかし**”いずれか”**という下記のような書き方はあるものの、**”両方とも”**のような書き方が検索してもみつけられず、特に試したことといえるものもない状況です。
|
245
|
-
|
246
|
-
```SQL
|
247
|
-
on base_action_record.target_id=(case when 条件
|
248
|
-
then t1.content_id
|
249
|
-
else base_record.attach_id end);
|
250
|
-
```
|
251
|
-
別の発想が必要なのか、検索が足りないのかわかりませんが、もしお心当たりのある方、上記ソースコードをスッキリさせられる方がいらっしゃいましたらお力添え頂けましたら幸甚に存じます。
|
252
|
-
宜しくお願い致します。
|
253
|
-
|
254
247
|
###補足情報(FW/ツールのバージョンなど)
|
255
248
|
phpMyAdmin(4.8.5)で、MySQL(10.0.33-MariaDB)を使っています。
|
1
画像添付など
title
CHANGED
File without changes
|
body
CHANGED
@@ -1,33 +1,39 @@
|
|
1
1
|
###前提
|
2
|
-
`jp_contents_table`
|
2
|
+
`jp_contents_table` テーブルから`path`のカラムが`/7`であるレコード(対象)を1件取得するSQLを書いています。
|
3
3
|
`path`のカラムの値は重複しないので必ず取得は1件です。
|
4
4
|
|
5
|
-
取得された「対象
|
5
|
+
取得された「対象」には、「添付データ」もありまして、それぞれに「アクション日」があります。
|
6
6
|
|
7
|
-
つまり、「対象
|
7
|
+
つまり、「対象」への「アクション日」や、「添付データ」への「アクション日」という具合です。
|
8
8
|
|
9
9
|
###質問
|
10
|
-
|
10
|
+
上のようにそれぞれの「アクション日」があるために`JOIN`させる`ON`が2通りあるのですが、その2通りのために`jp_contents_table` テーブルを2回呼んでいることにやや違和感を覚えています。これを改善したいです。
|
11
11
|
|
12
|
+
具体的には後述するソースコードで
|
13
|
+
「対象」
|
14
|
+
「対象へのアクション日」
|
15
|
+
「対象の投稿者」
|
16
|
+
「対象の添付データ」
|
17
|
+
「対象の添付データへのアクション日」
|
12
|
-
|
18
|
+
という目的の取得は手探りながらも実装できたのですが、`jp_contents_table` テーブルは下図のように「対象へのアクション日」と「対象の添付データへのアクション日」で必要なので、そのあたりの処理が冗長に思えるのです。
|
13
|
-
を2回呼んでいるのですが、
|
14
19
|
|
15
|
-
|
20
|
+
スッキリさせる方法はございますでしょうか。
|
16
21
|
|
17
|
-
|
22
|
+

|
18
23
|
|
24
|
+
|
19
25
|
###ソースコード
|
20
|
-
こちらが
|
26
|
+
こちらがその冗長さを覚えるというソースコードです。
|
21
27
|
|
22
|
-
`jp_contents_table`
|
28
|
+
`jp_contents_table` テーブルから`path`のカラムが`/7`であるレコード(対象)を1件取得して、上図のように連結しています。
|
23
29
|
|
24
30
|
リンク先SQL fiddleにある
|
25
|
-
|
31
|
+
50行目の`# 「対象へのアクション日」をjoin`
|
26
|
-
|
32
|
+
89行目の`# 「対象の添付データへのアクション日」をjoin`
|
27
|
-
が`
|
33
|
+
が`jp_contents_table` テーブルを2回呼んでいるという処理になります。
|
28
34
|
|
29
35
|
|
30
|
-
[下記のソースコードを実行する](http://sqlfiddle.com/#!9/
|
36
|
+
[下記のソースコードを実行する](http://sqlfiddle.com/#!9/062788/3)
|
31
37
|
```SQL
|
32
38
|
/*
|
33
39
|
■テーブルの構造
|
@@ -45,17 +51,17 @@
|
|
45
51
|
INSERT INTO jp_actions_table
|
46
52
|
(action_id, action_name, action_date, actor_id, target_id, target_type, target_country_code)
|
47
53
|
VALUES
|
48
|
-
(1, 'follow', '2020-01-
|
54
|
+
(1, 'follow', '2020-01-00 00:00:00', 1, 2, 'user', 'jp'),
|
49
|
-
(2, 'follow', '2020-02-
|
55
|
+
(2, 'follow', '2020-02-00 00:00:00', 1, 2, 'tag', ''),
|
50
|
-
(3, 'favorite', '2020-03-
|
56
|
+
(3, 'favorite', '2020-03-00 00:00:00', 1, 3, 'user', 'jp'),
|
51
|
-
(4, 'favorite', '2020-04-
|
57
|
+
(4, 'favorite', '2020-04-00 00:00:00', 2, 5, 'user', 'jp'),
|
52
|
-
(5, 'favorite', '2020-05-
|
58
|
+
(5, 'favorite', '2020-05-00 00:00:00', 1, 7, 'comment', 'jp'),
|
53
|
-
(6, 'block', '2020-
|
59
|
+
(6, 'block', '2020-06-00 08:00:00', 1, 3, 'user', 'jp'),
|
54
|
-
(7, 'favorite', '2020-07-
|
60
|
+
(7, 'favorite', '2020-07-00 07:00:00', 1, 5, 'user', 'jp'),
|
55
|
-
(8, 'favorite', '2020-08-
|
61
|
+
(8, 'favorite', '2020-08-00 08:00:00', 1, 5, 'movie', 'en'),
|
56
|
-
(9, 'favorite', '2020-09-
|
62
|
+
(9, 'favorite', '2020-09-00 09:00:00', 1, 3, 'user', 'ko'),
|
57
|
-
(10, 'favorite', '2020-10-
|
63
|
+
(10, 'favorite', '2020-10-00 10:00:00', 1, 3, 'thread', 'jp'),
|
58
|
-
(11, 'follow', '2020-11-
|
64
|
+
(11, 'follow', '2020-11-00 11:00:00', 1, 9, 'thread', 'jp')
|
59
65
|
;
|
60
66
|
|
61
67
|
# jp_contents
|
@@ -104,7 +110,7 @@
|
|
104
110
|
|
105
111
|
/*
|
106
112
|
■当SQLの概要
|
107
|
-
jp_contents_table から path='/7' を「対象
|
113
|
+
jp_contents_table から path='/7' を「対象」として取得します。
|
108
114
|
そして
|
109
115
|
「対象へのアクション日」
|
110
116
|
「対象の投稿者」
|
@@ -115,7 +121,7 @@
|
|
115
121
|
select *
|
116
122
|
from (
|
117
123
|
select
|
118
|
-
# 「対象
|
124
|
+
# 「対象」
|
119
125
|
t1.content_id
|
120
126
|
,t1.author_id
|
121
127
|
,t1.path
|
@@ -124,16 +130,17 @@
|
|
124
130
|
,t1.parent_content_id
|
125
131
|
,t1.content_type
|
126
132
|
,t1.content_text
|
133
|
+
,t1.attach_id
|
134
|
+
,t1.attach_type
|
135
|
+
,t1.attach_country_code
|
127
136
|
# 「対象へのアクション日」
|
128
137
|
,base_action_record.follow_date
|
129
138
|
,base_action_record.favorite_date
|
139
|
+
,base_action_record.block_date
|
130
140
|
# 「対象の投稿者」
|
131
141
|
,case when t1.attach_country_code='jp' and t1.attach_type='user'
|
132
142
|
then null else jp_a.nick_name end as author_nickname
|
133
143
|
# 「対象の添付データ」
|
134
|
-
,t1.attach_id
|
135
|
-
,t1.attach_type
|
136
|
-
,t1.attach_country_code
|
137
144
|
,case when t1.attach_country_code='jp' and t1.attach_type='user'
|
138
145
|
then jp_u.nick_name else null end as attached_nick_name
|
139
146
|
,case when t1.attach_country_code='jp' and t1.attach_type='user'
|
@@ -180,7 +187,7 @@
|
|
180
187
|
group by jp_actions.target_id, jp_actions.target_type, jp_actions.target_country_code
|
181
188
|
|
182
189
|
) as base_action_record
|
183
|
-
|
190
|
+
|
184
191
|
on base_action_record.target_id=t1.content_id
|
185
192
|
and base_action_record.target_type=t1.content_type
|
186
193
|
and base_action_record.target_country_code=t1.country_code
|
@@ -226,8 +233,23 @@
|
|
226
233
|
|
227
234
|
|
228
235
|
```
|
236
|
+
###試したこと
|
229
237
|
|
238
|
+
「対象」との連結が81行目のこちらで、
|
239
|
+
`on base_action_record.target_id=t1.content_id`
|
240
|
+
そして「対象の添付データ」との連結が123行目のこちらになるので、
|
241
|
+
`on attach_action_record.target_id=base_record.attach_id`
|
242
|
+
これらの条件をまとめてかければと思いました。
|
243
|
+
|
244
|
+
しかし**”いずれか”**という下記のような書き方はあるものの、**”両方とも”**のような書き方が検索してもみつけられず、特に試したことといえるものもない状況です。
|
245
|
+
|
246
|
+
```SQL
|
247
|
+
on base_action_record.target_id=(case when 条件
|
248
|
+
then t1.content_id
|
249
|
+
else base_record.attach_id end);
|
250
|
+
```
|
251
|
+
別の発想が必要なのか、検索が足りないのかわかりませんが、もしお心当たりのある方、上記ソースコードをスッキリさせられる方がいらっしゃいましたらお力添え頂けましたら幸甚に存じます。
|
252
|
+
宜しくお願い致します。
|
253
|
+
|
230
254
|
###補足情報(FW/ツールのバージョンなど)
|
231
|
-
phpMyAdmin(4.8.5)で、MySQL(10.0.33-MariaDB)を使っています。
|
255
|
+
phpMyAdmin(4.8.5)で、MySQL(10.0.33-MariaDB)を使っています。
|
232
|
-
|
233
|
-
効率的な方法がございましたら宜しくお願い致します。
|