質問編集履歴
11
SQLfiddleを修正
test
CHANGED
File without changes
|
test
CHANGED
@@ -16,7 +16,7 @@
|
|
16
16
|
|
17
17
|
|
18
18
|
|
19
|
-
[下記のコードを実行する(SQLfiddle)](http://sqlfiddle.com/#!9/b0a45e/
|
19
|
+
[下記のコードを実行する(SQLfiddle)](http://sqlfiddle.com/#!9/b0a45e/10)
|
20
20
|
|
21
21
|
```SQL
|
22
22
|
|
10
SQLfiddleを修正
test
CHANGED
File without changes
|
test
CHANGED
@@ -16,7 +16,7 @@
|
|
16
16
|
|
17
17
|
|
18
18
|
|
19
|
-
[下記のコードを実行する(SQLfiddle)](http://sqlfiddle.com/#!9/b0a45e/
|
19
|
+
[下記のコードを実行する(SQLfiddle)](http://sqlfiddle.com/#!9/b0a45e/9)
|
20
20
|
|
21
21
|
```SQL
|
22
22
|
|
9
SQLfiddleを修正
test
CHANGED
File without changes
|
test
CHANGED
@@ -16,7 +16,7 @@
|
|
16
16
|
|
17
17
|
|
18
18
|
|
19
|
-
[下記のコードを実行する(SQLfiddle)](http://sqlfiddle.com/#!9/b0a45e/
|
19
|
+
[下記のコードを実行する(SQLfiddle)](http://sqlfiddle.com/#!9/b0a45e/8)
|
20
20
|
|
21
21
|
```SQL
|
22
22
|
|
8
SQLfiddleを追記
test
CHANGED
File without changes
|
test
CHANGED
@@ -15,6 +15,8 @@
|
|
15
15
|
`on ●●➀`と`on ●●➁`という連結条件が違うので2回書かないといけないと思っていますが、重複させずにすっきりさせる方法はありますか?
|
16
16
|
|
17
17
|
|
18
|
+
|
19
|
+
[下記のコードを実行する(SQLfiddle)](http://sqlfiddle.com/#!9/b0a45e/4)
|
18
20
|
|
19
21
|
```SQL
|
20
22
|
|
7
自己解決したため編集
test
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
JOINのONが違うとき、同じSELECTを2回書かないといけませんか?
|
test
CHANGED
@@ -1,3 +1,81 @@
|
|
1
|
-
|
1
|
+
※自己解決し問題点が明確になったため、その本質に不要な細部を●●と抽象した内容で以下編集致しました。
|
2
2
|
|
3
|
+
|
4
|
+
|
3
|
-
|
5
|
+
コメントをくださったお二方、どうもありがとうございました。
|
6
|
+
|
7
|
+
|
8
|
+
|
9
|
+
###質問
|
10
|
+
|
11
|
+
以下`#join➀`と`#join➁`について、`left outer join ( この中 )`に同じ処理を重複して書いてしまい、冗長に感じています。
|
12
|
+
|
13
|
+
|
14
|
+
|
15
|
+
`on ●●➀`と`on ●●➁`という連結条件が違うので2回書かないといけないと思っていますが、重複させずにすっきりさせる方法はありますか?
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
```SQL
|
20
|
+
|
21
|
+
select *
|
22
|
+
|
23
|
+
from (
|
24
|
+
|
25
|
+
select ●●
|
26
|
+
|
27
|
+
from ●●
|
28
|
+
|
29
|
+
|
30
|
+
|
31
|
+
left join ●●
|
32
|
+
|
33
|
+
on ●●
|
34
|
+
|
35
|
+
left join ●●
|
36
|
+
|
37
|
+
on ●●
|
38
|
+
|
39
|
+
left join ●●
|
40
|
+
|
41
|
+
on ●●
|
42
|
+
|
43
|
+
|
44
|
+
|
45
|
+
# join➀
|
46
|
+
|
47
|
+
left outer join (
|
48
|
+
|
49
|
+
select ●●
|
50
|
+
|
51
|
+
from ●●
|
52
|
+
|
53
|
+
where ●●
|
54
|
+
|
55
|
+
) as ●●
|
56
|
+
|
57
|
+
on ●●➀
|
58
|
+
|
59
|
+
|
60
|
+
|
61
|
+
where ●●
|
62
|
+
|
63
|
+
) as ●●
|
64
|
+
|
65
|
+
|
66
|
+
|
67
|
+
# join➁
|
68
|
+
|
69
|
+
left outer join (
|
70
|
+
|
71
|
+
select ●●
|
72
|
+
|
73
|
+
from ●●
|
74
|
+
|
75
|
+
where ●●
|
76
|
+
|
77
|
+
) as ●●
|
78
|
+
|
79
|
+
on ●●➁
|
80
|
+
|
81
|
+
```
|
6
編集中
test
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
こちらの質問は現在編集中です
|
test
CHANGED
@@ -1,505 +1,3 @@
|
|
1
|
-
|
1
|
+
質問が大変わかりにくかったため要点を絞るべく編集中です。
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
`path`のカラムの値は重複しないので必ず取得は1件です。
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
取得された「対象」には、「対象の添付データ」もありまして、それぞれに「アクション日」があります。
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
つまり、「対象へのアクション日」や「対象の添付データへのアクション日」という具合です。
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
###質問
|
18
|
-
|
19
|
-
上のようにそれぞれの「アクション日」があるために`JOIN`させる`ON`が2通りあるのですが、その2通りのために`jp_actions_table`テーブルに2回同じ処理をしていることに違和感を覚えています。これを改善したいです。
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
図でいうと緑の部分で、SQLfiddleでいうと50行目と80行目です。
|
26
|
-
|
27
|
-
![![イメージ説明](f7775bef90d23dba95d42257cb1ab4d6.jpeg)
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
得たい結果は上図レコードで、`user_id=1`さん(彼)が`path='/7'`のページ(対象)を閲覧している仮定の結果です。
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
この結果は1~5のロジックで得られ、2と5で`jp_actions_table`に同じ処理をしている下記ソースコードに冗長さを覚えます。
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
1.「対象」を取得(図のオレンジ)
|
40
|
-
|
41
|
-
`jp_contents_table`から`path='/7'`のレコードを1件取得
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
2.「対象へのアクション日」を取得(図の緑)
|
46
|
-
|
47
|
-
彼が「対象」を`follow`した日が欲しい。そこで`jp_actions_table`から`action_date`を取得。そして`follow`対象である`target_id`と、「対象」の`content_id`で連結。
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
3.「対象の投稿者」を連結(図の青)
|
52
|
-
|
53
|
-
誰が対象を投稿したのかが欲しい。そこで`jp_contents_table`の`author_id`と、`jp_users_table`の`user_id`で連結。
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
4.「対象の添付データ」を連結(図の紫)
|
58
|
-
|
59
|
-
対象に添付データがあれば欲しい。そこで`jp_contents_table`の`attach_id`と、`jp_users_table`または`jp_content_table`で連結。
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
5.「対象の添付データへのアクション日」を連結(図の緑)
|
64
|
-
|
65
|
-
彼が「対象の添付データ」を`follow`した日が欲しい。そこで`jp_actions_table`から`action_date`を取得。そして`follow`対象である`target_id`と、「対象」の`attach_id`で連結。
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
###ソースコード
|
72
|
-
|
73
|
-
こちらが1~5のソースコードです。
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
リンク先SQLfiddleにある
|
78
|
-
|
79
|
-
50行目の`# 「対象へのアクション日」をjoin`
|
80
|
-
|
81
|
-
89行目の`# 「対象の添付データへのアクション日」をjoin`
|
82
|
-
|
83
|
-
が`jp_actions_table` テーブルに同じ処理を2回している部分です。
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
50行目も89行目も、`left outer join ( この中 )`は同じなのに、`JOIN`させる`ON`が違うだけという理由で2回書いているのですが、スッキリさせられませんでしょうか。
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
[下記のソースコードを実行する(SQLfiddle)](http://sqlfiddle.com/#!9/062788/3)
|
92
|
-
|
93
|
-
```SQL
|
94
|
-
|
95
|
-
/*
|
96
|
-
|
97
|
-
■テーブルの構造
|
98
|
-
|
99
|
-
掲示板サイトのテーブルで、以下4つがあります。
|
100
|
-
|
101
|
-
・jp_actions_table : アクション
|
102
|
-
|
103
|
-
・jp_contents_table : コンテンツ
|
104
|
-
|
105
|
-
・jp_users _table : ユーザー
|
106
|
-
|
107
|
-
*/
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
# jp_actions
|
112
|
-
|
113
|
-
# アクションのテーブル
|
114
|
-
|
115
|
-
CREATE TABLE jp_actions_table
|
116
|
-
|
117
|
-
(action_id int, action_name text, action_date text, actor_id int, target_id int, target_type text, target_country_code text)
|
118
|
-
|
119
|
-
;
|
120
|
-
|
121
|
-
INSERT INTO jp_actions_table
|
122
|
-
|
123
|
-
(action_id, action_name, action_date, actor_id, target_id, target_type, target_country_code)
|
124
|
-
|
125
|
-
VALUES
|
126
|
-
|
127
|
-
(1, 'follow', '2020-01-00 00:00:00', 1, 2, 'user', 'jp'),
|
128
|
-
|
129
|
-
(2, 'follow', '2020-02-00 00:00:00', 1, 2, 'tag', ''),
|
130
|
-
|
131
|
-
(3, 'favorite', '2020-03-00 00:00:00', 1, 3, 'user', 'jp'),
|
132
|
-
|
133
|
-
(4, 'favorite', '2020-04-00 00:00:00', 2, 5, 'user', 'jp'),
|
134
|
-
|
135
|
-
(5, 'favorite', '2020-05-00 00:00:00', 1, 7, 'comment', 'jp'),
|
136
|
-
|
137
|
-
(6, 'block', '2020-06-00 08:00:00', 1, 3, 'user', 'jp'),
|
138
|
-
|
139
|
-
(7, 'favorite', '2020-07-00 07:00:00', 1, 5, 'user', 'jp'),
|
140
|
-
|
141
|
-
(8, 'favorite', '2020-08-00 08:00:00', 1, 5, 'movie', 'en'),
|
142
|
-
|
143
|
-
(9, 'favorite', '2020-09-00 09:00:00', 1, 3, 'user', 'ko'),
|
144
|
-
|
145
|
-
(10, 'favorite', '2020-10-00 10:00:00', 1, 3, 'thread', 'jp'),
|
146
|
-
|
147
|
-
(11, 'follow', '2020-11-00 11:00:00', 1, 9, 'thread', 'jp')
|
148
|
-
|
149
|
-
;
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
# jp_contents
|
154
|
-
|
155
|
-
# jpのコンテンツのテーブル
|
156
|
-
|
157
|
-
CREATE TABLE jp_contents_table
|
158
|
-
|
159
|
-
(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)
|
160
|
-
|
161
|
-
;
|
162
|
-
|
163
|
-
INSERT INTO jp_contents_table
|
164
|
-
|
165
|
-
(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)
|
166
|
-
|
167
|
-
VALUES
|
168
|
-
|
169
|
-
(1, 0, '/1', '2020-01-00 00:00:00', 0, 0, 'en', 'drama', 'Mr.ROBOT', 0, '', ''),
|
170
|
-
|
171
|
-
(2, 3, '/2', '2020-02-00 00:00:00', 0, 0, 'jp', 'thread', '韓国の映画について語るスレ', 0, '', ''),
|
172
|
-
|
173
|
-
(3, 3, '/3', '2020-03-00 00:00:00', 0, 0, 'jp', 'thread', '米国の映画について語るスレ', 0, '', ''),
|
174
|
-
|
175
|
-
(4, 3, '/4', '2020-04-00 00:00:00', 3, 0, 'jp', 'comment', '米国のお勧め映画は何ですか?', 0, '', ''),
|
176
|
-
|
177
|
-
(5, 0, '/5', '2020-05-00 00:00:00', 0, 0, 'ko', 'manga', '지안', 0, '', ''),
|
178
|
-
|
179
|
-
(6, 1, '/6', '2020-06-00 00:00:00', 3, 4, 'jp', 'reply', '米国のMr.ROBOTを添付します。', 4, 'drama', 'en'),
|
180
|
-
|
181
|
-
(7, 4, '/7', '2020-07-00 00:00:00', 2, 0, 'jp', 'comment', '韓国の지안さんを添付します。', 3, 'user', 'ko'),
|
182
|
-
|
183
|
-
(8, 1, '/8', '2020-08-00 00:00:00', 3, 6, 'jp', 'reply', '面白そうですね。', 0, '', ''),
|
184
|
-
|
185
|
-
(9, 3, '/9', '2020-09-00 00:00:00', 3, 6, 'jp', 'reply', '良いですね。', 0, '', ''),
|
186
|
-
|
187
|
-
(10, 2, '/10', '2020-10-00 00:00:00', 3, 9, 'jp', 'reply', 'ええ、とても良いですよ。', 0, '', ''),
|
188
|
-
|
189
|
-
(11, 3, '/11', '2020-11-00 00:00:00', 0, 0, 'jp', 'thread', '日本の田中家について語るスレ', 0, '', ''),
|
190
|
-
|
191
|
-
(12, 1, '/12', '2020-12-00 00:00:00', 11, 0, 'jp', 'comment', '日本の三郎さんを添付します。', 3, 'user', 'jp'),
|
192
|
-
|
193
|
-
(13, 2, '/13', '2020-13-00 00:00:00', 2, 0, 'jp', 'comment', '米国の映画スレを添付します', 9, 'thread', 'jp'),
|
194
|
-
|
195
|
-
(14, 0, '/14', '2020-14-00 00:00:00', 0, 0, 'en', 'user', 'smith', 0, '', ''),
|
196
|
-
|
197
|
-
(15, 0, '/15', '2020-15-00 00:00:00', 0, 0, 'zh', 'manga', '砂輿海之歌', 0, '', ''),
|
198
|
-
|
199
|
-
(16, 0, '/16', '2020-16-00 00:00:00', 0, 0, 'en', 'movie', 'Avator', 0, '', ''),
|
200
|
-
|
201
|
-
(17, 0, '/17', '2020-17-00 00:00:00', 0, 0, 'ru', 'movie', 'Хардкор', 0, '', ''),
|
202
|
-
|
203
|
-
(18, 0, '/18', '2020-18-00 00:00:00', 0, 0, 'zh', 'drama', '大秦帝国', 0, '', '')
|
204
|
-
|
205
|
-
;
|
206
|
-
|
207
|
-
# jp_users
|
208
|
-
|
209
|
-
# ユーザーのテーブル
|
210
|
-
|
211
|
-
CREATE TABLE jp_users_table
|
212
|
-
|
213
|
-
(user_id int, unique_name text, nick_name text)
|
214
|
-
|
215
|
-
;
|
216
|
-
|
217
|
-
INSERT INTO jp_users_table
|
218
|
-
|
219
|
-
(user_id, unique_name, nick_name)
|
220
|
-
|
221
|
-
VALUES
|
222
|
-
|
223
|
-
(1, 'ichiro', '田中一郎'),
|
224
|
-
|
225
|
-
(2, 'jiro', '田中二郎'),
|
226
|
-
|
227
|
-
(3, 'saburo', '田中三郎'),
|
228
|
-
|
229
|
-
(4, 'shiro', '田中四郎'),
|
230
|
-
|
231
|
-
(5, 'goro', '山田五郎'),
|
232
|
-
|
233
|
-
(6, 'rokuro', '山田六郎'),
|
234
|
-
|
235
|
-
(7, 'nanaro', '山田七郎')
|
236
|
-
|
237
|
-
;
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
/*
|
242
|
-
|
243
|
-
■当SQLの概要
|
244
|
-
|
245
|
-
jp_contents_table から path='/7' を「対象」として取得します。
|
246
|
-
|
247
|
-
そして
|
248
|
-
|
249
|
-
「対象へのアクション日」
|
250
|
-
|
251
|
-
「対象の投稿者」
|
252
|
-
|
253
|
-
「対象の添付データ」
|
254
|
-
|
255
|
-
「対象の添付データへのアクション日」
|
256
|
-
|
257
|
-
も併せて取得します
|
258
|
-
|
259
|
-
*/
|
260
|
-
|
261
|
-
select *
|
262
|
-
|
263
|
-
from (
|
264
|
-
|
265
|
-
select
|
266
|
-
|
267
|
-
# 「対象」
|
268
|
-
|
269
|
-
t1.content_id
|
270
|
-
|
271
|
-
,t1.author_id
|
272
|
-
|
273
|
-
,t1.path
|
274
|
-
|
275
|
-
,t1.content_date
|
276
|
-
|
277
|
-
,t1.parent_thread_id
|
278
|
-
|
279
|
-
,t1.parent_content_id
|
280
|
-
|
281
|
-
,t1.content_type
|
282
|
-
|
283
|
-
,t1.content_text
|
284
|
-
|
285
|
-
,t1.attach_id
|
286
|
-
|
287
|
-
,t1.attach_type
|
288
|
-
|
289
|
-
,t1.attach_country_code
|
290
|
-
|
291
|
-
# 「対象へのアクション日」
|
292
|
-
|
293
|
-
,base_action_record.follow_date
|
294
|
-
|
295
|
-
,base_action_record.favorite_date
|
296
|
-
|
297
|
-
,base_action_record.block_date
|
298
|
-
|
299
|
-
# 「対象の投稿者」
|
300
|
-
|
301
|
-
,case when t1.attach_country_code='jp' and t1.attach_type='user'
|
302
|
-
|
303
|
-
then null else jp_a.nick_name end as author_nickname
|
304
|
-
|
305
|
-
# 「対象の添付データ」
|
306
|
-
|
307
|
-
,case when t1.attach_country_code='jp' and t1.attach_type='user'
|
308
|
-
|
309
|
-
then jp_u.nick_name else null end as attached_nick_name
|
310
|
-
|
311
|
-
,case when t1.attach_country_code='jp' and t1.attach_type='user'
|
312
|
-
|
313
|
-
then null else jp_c.content_text end as attached_content_text
|
314
|
-
|
315
|
-
from jp_contents_table t1
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
# 「対象の投稿者」をjoin
|
320
|
-
|
321
|
-
left join jp_users_table jp_a
|
322
|
-
|
323
|
-
on t1.author_id=jp_a.user_id
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
# 「対象の添付データ」をjoin
|
328
|
-
|
329
|
-
left join jp_users_table jp_u
|
330
|
-
|
331
|
-
on t1.attach_id=jp_u.user_id
|
332
|
-
|
333
|
-
left join jp_contents_table jp_c
|
334
|
-
|
335
|
-
on t1.attach_id=jp_c.content_id
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
# 「対象へのアクション日」をjoin
|
340
|
-
|
341
|
-
left outer join (
|
342
|
-
|
343
|
-
select jp_actions.target_id
|
344
|
-
|
345
|
-
,jp_actions.target_type
|
346
|
-
|
347
|
-
,jp_actions.target_country_code
|
348
|
-
|
349
|
-
,max( case
|
350
|
-
|
351
|
-
when jp_actions.action_name='follow'
|
352
|
-
|
353
|
-
then jp_actions.action_date
|
354
|
-
|
355
|
-
end ) as follow_date
|
356
|
-
|
357
|
-
,max( case
|
358
|
-
|
359
|
-
when jp_actions.action_name='favorite'
|
360
|
-
|
361
|
-
then jp_actions.action_date
|
362
|
-
|
363
|
-
end ) as favorite_date
|
364
|
-
|
365
|
-
,max( case
|
366
|
-
|
367
|
-
when jp_actions.action_name='block'
|
368
|
-
|
369
|
-
then jp_actions.action_date
|
370
|
-
|
371
|
-
end ) as block_date
|
372
|
-
|
373
|
-
from jp_actions_table jp_actions
|
374
|
-
|
375
|
-
# 実行者1のアクション
|
376
|
-
|
377
|
-
where jp_actions.actor_id=1
|
378
|
-
|
379
|
-
and jp_actions.action_name in ('favorite','follow','block')
|
380
|
-
|
381
|
-
and exists(
|
382
|
-
|
383
|
-
select 0 from jp_actions_table
|
384
|
-
|
385
|
-
where target_id=jp_actions.target_id
|
386
|
-
|
387
|
-
and action_name in ('favorite','follow','block')
|
388
|
-
|
389
|
-
)
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
group by jp_actions.target_id, jp_actions.target_type, jp_actions.target_country_code
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
) as base_action_record
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
on base_action_record.target_id=t1.content_id
|
402
|
-
|
403
|
-
and base_action_record.target_type=t1.content_type
|
404
|
-
|
405
|
-
and base_action_record.target_country_code=t1.country_code
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
# 取得をpathで指定(country_codeとcontent_typeにindexあり)
|
410
|
-
|
411
|
-
where t1.path='/7' and t1.country_code='jp' and t1.content_type='comment'
|
412
|
-
|
413
|
-
) as base_record
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
# 「対象の添付データへのアクション日」をjoin
|
418
|
-
|
419
|
-
left outer join (
|
420
|
-
|
421
|
-
select jp_actions.target_id
|
422
|
-
|
423
|
-
,jp_actions.target_type
|
424
|
-
|
425
|
-
,jp_actions.target_country_code
|
426
|
-
|
427
|
-
,max( case
|
428
|
-
|
429
|
-
when jp_actions.action_name='follow'
|
430
|
-
|
431
|
-
then jp_actions.action_date
|
432
|
-
|
433
|
-
end ) as attached_follow_date
|
434
|
-
|
435
|
-
,max( case
|
436
|
-
|
437
|
-
when jp_actions.action_name='favorite'
|
438
|
-
|
439
|
-
then jp_actions.action_date
|
440
|
-
|
441
|
-
end ) as attached_favorite_date
|
442
|
-
|
443
|
-
,max( case
|
444
|
-
|
445
|
-
when jp_actions.action_name='block'
|
446
|
-
|
447
|
-
then jp_actions.action_date
|
448
|
-
|
449
|
-
end ) as attached_block_date
|
450
|
-
|
451
|
-
from jp_actions_table jp_actions
|
452
|
-
|
453
|
-
# 実行者1のアクション
|
454
|
-
|
455
|
-
where jp_actions.actor_id=1
|
456
|
-
|
457
|
-
and jp_actions.action_name in ('favorite','follow','block')
|
458
|
-
|
459
|
-
and exists(
|
460
|
-
|
461
|
-
select 0 from jp_actions_table
|
462
|
-
|
463
|
-
where target_id=jp_actions.target_id
|
464
|
-
|
465
|
-
and action_name in ('favorite','follow','block')
|
466
|
-
|
467
|
-
)
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
group by jp_actions.target_id, jp_actions.target_type, jp_actions.target_country_code
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
) as attach_action_record
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
on attach_action_record.target_id=base_record.attach_id
|
480
|
-
|
481
|
-
and attach_action_record.target_type=base_record.attach_type
|
482
|
-
|
483
|
-
and attach_action_record.target_country_code=base_record.attach_country_code
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
```
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
###補足情報(FW/ツールのバージョンなど)
|
498
|
-
|
499
|
-
phpMyAdmin(4.8.5)で、MySQL(10.0.33-MariaDB)を使っています。
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
※編集(2020-02-18)
|
504
|
-
|
505
|
-
質問の項目に「どういうロジック」を1~5のように追記させて頂きました。その際に文字数制限がきてしまったため、試したことの項目を削除致しました。
|
3
|
+
ご迷惑おかけして申し訳ございません。
|
5
誤字などの訂正
test
CHANGED
@@ -1 +1 @@
|
|
1
|
-
SQLで、JOINのONが異なる場合、同じ
|
1
|
+
SQLで、JOINのONが異なる場合、JOINの内容が同じでも2回書かないといけませんか?
|
test
CHANGED
@@ -16,15 +16,19 @@
|
|
16
16
|
|
17
17
|
###質問
|
18
18
|
|
19
|
-
上のようにそれぞれの「アクション日」があるために`JOIN`させる`ON`が2通りあるのですが、その2通りのために`jp_actions_table`テーブルに2回同じ処理をしていること
|
19
|
+
上のようにそれぞれの「アクション日」があるために`JOIN`させる`ON`が2通りあるのですが、その2通りのために`jp_actions_table`テーブルに2回同じ処理をしていることに違和感を覚えています。これを改善したいです。
|
20
|
+
|
21
|
+
|
22
|
+
|
23
|
+
|
24
|
+
|
20
|
-
|
25
|
+
図でいうと緑の部分で、SQLfiddleでいうと50行目と80行目です。
|
21
|
-
|
22
26
|
|
23
27
|
![![イメージ説明](f7775bef90d23dba95d42257cb1ab4d6.jpeg)
|
24
28
|
|
25
29
|
|
26
30
|
|
27
|
-
得たい結果は上図レコードで、`user_id=1`さん(彼)が`path='/7'`のページ(対象)を閲覧している
|
31
|
+
得たい結果は上図レコードで、`user_id=1`さん(彼)が`path='/7'`のページ(対象)を閲覧している仮定の結果です。
|
28
32
|
|
29
33
|
|
30
34
|
|
@@ -44,21 +48,21 @@
|
|
44
48
|
|
45
49
|
|
46
50
|
|
47
|
-
3.「対象の投稿者」を
|
51
|
+
3.「対象の投稿者」を連結(図の青)
|
48
52
|
|
49
53
|
誰が対象を投稿したのかが欲しい。そこで`jp_contents_table`の`author_id`と、`jp_users_table`の`user_id`で連結。
|
50
54
|
|
51
55
|
|
52
56
|
|
53
|
-
4.「対象の添付データ」を
|
57
|
+
4.「対象の添付データ」を連結(図の紫)
|
54
58
|
|
55
59
|
対象に添付データがあれば欲しい。そこで`jp_contents_table`の`attach_id`と、`jp_users_table`または`jp_content_table`で連結。
|
56
60
|
|
57
61
|
|
58
62
|
|
59
|
-
5.「対象の添付データへのアクション日」(図の緑)
|
63
|
+
5.「対象の添付データへのアクション日」を連結(図の緑)
|
60
|
-
|
64
|
+
|
61
|
-
彼が「対象の添付データ」を`follow`した日が欲しい。そこで`jp_actions_table`から`action_date`を取得。そして`follow`対象である`target_id`と、「対象
|
65
|
+
彼が「対象の添付データ」を`follow`した日が欲しい。そこで`jp_actions_table`から`action_date`を取得。そして`follow`対象である`target_id`と、「対象」の`attach_id`で連結。
|
62
66
|
|
63
67
|
|
64
68
|
|
@@ -66,11 +70,7 @@
|
|
66
70
|
|
67
71
|
###ソースコード
|
68
72
|
|
69
|
-
こちらが
|
73
|
+
こちらが1~5のソースコードです。
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
`jp_contents_table` テーブルから`path`のカラムが`/7`であるレコード(対象)を1件取得して、上図のように連結しています。
|
74
74
|
|
75
75
|
|
76
76
|
|
@@ -88,7 +88,7 @@
|
|
88
88
|
|
89
89
|
|
90
90
|
|
91
|
-
[下記のソースコードを実行する](http://sqlfiddle.com/#!9/062788/3)
|
91
|
+
[下記のソースコードを実行する(SQLfiddle)](http://sqlfiddle.com/#!9/062788/3)
|
92
92
|
|
93
93
|
```SQL
|
94
94
|
|
4
誤字などの訂正
test
CHANGED
File without changes
|
test
CHANGED
@@ -1,22 +1,22 @@
|
|
1
1
|
###前提
|
2
2
|
|
3
|
-
`jp_contents_table`
|
3
|
+
`jp_contents_table`テーブルから`path`のカラムが`/7`であるレコード(対象)を1件取得するSQLを書いています。
|
4
4
|
|
5
5
|
`path`のカラムの値は重複しないので必ず取得は1件です。
|
6
6
|
|
7
7
|
|
8
8
|
|
9
|
-
取得された「対象」には、「添付データ」もありまして、それぞれに「アクション日」があります。
|
9
|
+
取得された「対象」には、「対象の添付データ」もありまして、それぞれに「アクション日」があります。
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
|
11
|
+
|
12
|
+
|
13
|
-
つまり、「対象
|
13
|
+
つまり、「対象へのアクション日」や「対象の添付データへのアクション日」という具合です。
|
14
14
|
|
15
15
|
|
16
16
|
|
17
17
|
###質問
|
18
18
|
|
19
|
-
上のようにそれぞれの「アクション日」があるために`JOIN`させる`ON`が2通りあるのですが、その2通りのために`jp_actions_table`
|
19
|
+
上のようにそれぞれの「アクション日」があるために`JOIN`させる`ON`が2通りあるのですが、その2通りのために`jp_actions_table`テーブルに2回同じ処理をしていること(図の緑)に違和感を覚えています。これを改善したいです。
|
20
20
|
|
21
21
|
|
22
22
|
|
@@ -24,11 +24,11 @@
|
|
24
24
|
|
25
25
|
|
26
26
|
|
27
|
-
得たい結果は上図で、
|
27
|
+
得たい結果は上図レコードで、`user_id=1`さん(彼)が`path='/7'`のページ(対象)を閲覧している設定の結果です。
|
28
|
-
|
29
|
-
|
30
|
-
|
28
|
+
|
29
|
+
|
30
|
+
|
31
|
-
この
|
31
|
+
この結果は1~5のロジックで得られ、2と5で`jp_actions_table`に同じ処理をしている下記ソースコードに冗長さを覚えます。
|
32
32
|
|
33
33
|
|
34
34
|
|
@@ -40,7 +40,7 @@
|
|
40
40
|
|
41
41
|
2.「対象へのアクション日」を取得(図の緑)
|
42
42
|
|
43
|
-
彼が「対象」を`follow`した日が欲しい。そこで`jp_actions_table`から`action_date`を取得。そして`follow`対象である`target_id`と、「対象」の`content_id`で連結。
|
43
|
+
彼が「対象」を`follow`した日が欲しい。そこで`jp_actions_table`から`action_date`を取得。そして`follow`対象である`target_id`と、「対象」の`content_id`で連結。
|
44
44
|
|
45
45
|
|
46
46
|
|
@@ -58,7 +58,7 @@
|
|
58
58
|
|
59
59
|
5.「対象の添付データへのアクション日」(図の緑)
|
60
60
|
|
61
|
-
彼が「対象の添付データ」を`follow`した日が欲しい。そこで`jp_actions_table`から`action_date`を取得。そして`follow`対象である`target_id`と、「対象の添付データ」の`content_id`で連結。
|
61
|
+
彼が「対象の添付データ」を`follow`した日が欲しい。そこで`jp_actions_table`から`action_date`を取得。そして`follow`対象である`target_id`と、「対象の添付データ」の`content_id`で連結。
|
62
62
|
|
63
63
|
|
64
64
|
|
@@ -74,15 +74,17 @@
|
|
74
74
|
|
75
75
|
|
76
76
|
|
77
|
-
リンク先SQL
|
77
|
+
リンク先SQLfiddleにある
|
78
78
|
|
79
79
|
50行目の`# 「対象へのアクション日」をjoin`
|
80
80
|
|
81
81
|
89行目の`# 「対象の添付データへのアクション日」をjoin`
|
82
82
|
|
83
|
-
が`jp_actions_table` テーブルを2回
|
83
|
+
が`jp_actions_table` テーブルに同じ処理を2回している部分です。
|
84
|
+
|
85
|
+
|
86
|
+
|
84
|
-
|
87
|
+
50行目も89行目も、`left outer join ( この中 )`は同じなのに、`JOIN`させる`ON`が違うだけという理由で2回書いているのですが、スッキリさせられませんでしょうか。
|
85
|
-
|
86
88
|
|
87
89
|
|
88
90
|
|
3
誤字などを修正
test
CHANGED
File without changes
|
test
CHANGED
@@ -28,7 +28,7 @@
|
|
28
28
|
|
29
29
|
|
30
30
|
|
31
|
-
この取得が以下1~5のロジックでして、2と5で同じ`jp_actions_table`が呼ばれ
|
31
|
+
この取得が以下1~5のロジックでして、2と5で同じ`jp_actions_table`が呼ばれるのですた、下記ソースコードに冗長さを覚えます。
|
32
32
|
|
33
33
|
|
34
34
|
|
@@ -46,13 +46,13 @@
|
|
46
46
|
|
47
47
|
3.「対象の投稿者」を取得(図の青)
|
48
48
|
|
49
|
-
誰が対象を投稿したのかが欲しい。そこで`jp_content_table`の`author_id`と、`jp_users`の`user_id`で連結。
|
49
|
+
誰が対象を投稿したのかが欲しい。そこで`jp_contents_table`の`author_id`と、`jp_users_table`の`user_id`で連結。
|
50
50
|
|
51
51
|
|
52
52
|
|
53
53
|
4.「対象の添付データ」を取得(図の紫)
|
54
54
|
|
55
|
-
対象に添付データがあれば欲しいそこで`jp_content_table`の`attach_id`と、`jp_users`または`jp_content_table`で連結。
|
55
|
+
対象に添付データがあれば欲しい。そこで`jp_contents_table`の`attach_id`と、`jp_users_table`または`jp_content_table`で連結。
|
56
56
|
|
57
57
|
|
58
58
|
|
@@ -490,6 +490,14 @@
|
|
490
490
|
|
491
491
|
|
492
492
|
|
493
|
+
|
494
|
+
|
493
495
|
###補足情報(FW/ツールのバージョンなど)
|
494
496
|
|
495
497
|
phpMyAdmin(4.8.5)で、MySQL(10.0.33-MariaDB)を使っています。
|
498
|
+
|
499
|
+
|
500
|
+
|
501
|
+
※編集(2020-02-18)
|
502
|
+
|
503
|
+
質問の項目に「どういうロジック」を1~5のように追記させて頂きました。その際に文字数制限がきてしまったため、試したことの項目を削除致しました。
|
2
どういうロジックでどういう結果を得たいかを追記させて頂きました。
test
CHANGED
File without changes
|
test
CHANGED
@@ -16,13 +16,233 @@
|
|
16
16
|
|
17
17
|
###質問
|
18
18
|
|
19
|
-
上のようにそれぞれの「アクション日」があるために`JOIN`させる`ON`が2通りあるのですが、その2通りのために`jp_con
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
19
|
+
上のようにそれぞれの「アクション日」があるために`JOIN`させる`ON`が2通りあるのですが、その2通りのために`jp_actions_table` テーブルを2回呼んでいること(図の緑)にやや違和感を覚えています。これを改善したいです。
|
20
|
+
|
21
|
+
|
22
|
+
|
23
|
+
![![イメージ説明](f7775bef90d23dba95d42257cb1ab4d6.jpeg)
|
24
|
+
|
25
|
+
|
26
|
+
|
27
|
+
得たい結果は上図で、これは`user_id=1`さん(彼)が、`path='/7'`のページ(対象)を閲覧している設定における取得結果です。
|
28
|
+
|
29
|
+
|
30
|
+
|
31
|
+
この取得が以下1~5のロジックでして、2と5で同じ`jp_actions_table`が呼ばれ冗長に思えるのです。
|
32
|
+
|
33
|
+
|
34
|
+
|
35
|
+
1.「対象」を取得(図のオレンジ)
|
36
|
+
|
37
|
+
`jp_contents_table`から`path='/7'`のレコードを1件取得
|
38
|
+
|
39
|
+
|
40
|
+
|
41
|
+
2.「対象へのアクション日」を取得(図の緑)
|
42
|
+
|
43
|
+
彼が「対象」を`follow`した日が欲しい。そこで`jp_actions_table`から`action_date`を取得。そして`follow`対象である`target_id`と、「対象」の`content_id`で連結。(SQLfidleの50行目がこれです)
|
44
|
+
|
45
|
+
|
46
|
+
|
47
|
+
3.「対象の投稿者」を取得(図の青)
|
48
|
+
|
49
|
+
誰が対象を投稿したのかが欲しい。そこで`jp_content_table`の`author_id`と、`jp_users`の`user_id`で連結。
|
50
|
+
|
51
|
+
|
52
|
+
|
53
|
+
4.「対象の添付データ」を取得(図の紫)
|
54
|
+
|
55
|
+
対象に添付データがあれば欲しいそこで`jp_content_table`の`attach_id`と、`jp_users`または`jp_content_table`で連結。
|
56
|
+
|
57
|
+
|
58
|
+
|
59
|
+
5.「対象の添付データへのアクション日」(図の緑)
|
60
|
+
|
61
|
+
彼が「対象の添付データ」を`follow`した日が欲しい。そこで`jp_actions_table`から`action_date`を取得。そして`follow`対象である`target_id`と、「対象の添付データ」の`content_id`で連結。(SQLfidleの89行目がこれです)
|
62
|
+
|
63
|
+
|
64
|
+
|
65
|
+
|
66
|
+
|
67
|
+
###ソースコード
|
68
|
+
|
69
|
+
こちらがその冗長さを覚えるというソースコードです。
|
70
|
+
|
71
|
+
|
72
|
+
|
73
|
+
`jp_contents_table` テーブルから`path`のカラムが`/7`であるレコード(対象)を1件取得して、上図のように連結しています。
|
74
|
+
|
75
|
+
|
76
|
+
|
77
|
+
リンク先SQL fiddleにある
|
78
|
+
|
79
|
+
50行目の`# 「対象へのアクション日」をjoin`
|
80
|
+
|
81
|
+
89行目の`# 「対象の添付データへのアクション日」をjoin`
|
82
|
+
|
83
|
+
が`jp_actions_table` テーブルを2回呼んでいるという処理になります。
|
84
|
+
|
85
|
+
|
86
|
+
|
87
|
+
|
88
|
+
|
89
|
+
[下記のソースコードを実行する](http://sqlfiddle.com/#!9/062788/3)
|
90
|
+
|
91
|
+
```SQL
|
92
|
+
|
93
|
+
/*
|
94
|
+
|
95
|
+
■テーブルの構造
|
96
|
+
|
97
|
+
掲示板サイトのテーブルで、以下4つがあります。
|
98
|
+
|
99
|
+
・jp_actions_table : アクション
|
100
|
+
|
101
|
+
・jp_contents_table : コンテンツ
|
102
|
+
|
103
|
+
・jp_users _table : ユーザー
|
104
|
+
|
105
|
+
*/
|
106
|
+
|
107
|
+
|
108
|
+
|
109
|
+
# jp_actions
|
110
|
+
|
111
|
+
# アクションのテーブル
|
112
|
+
|
113
|
+
CREATE TABLE jp_actions_table
|
114
|
+
|
115
|
+
(action_id int, action_name text, action_date text, actor_id int, target_id int, target_type text, target_country_code text)
|
116
|
+
|
117
|
+
;
|
118
|
+
|
119
|
+
INSERT INTO jp_actions_table
|
120
|
+
|
121
|
+
(action_id, action_name, action_date, actor_id, target_id, target_type, target_country_code)
|
122
|
+
|
123
|
+
VALUES
|
124
|
+
|
125
|
+
(1, 'follow', '2020-01-00 00:00:00', 1, 2, 'user', 'jp'),
|
126
|
+
|
127
|
+
(2, 'follow', '2020-02-00 00:00:00', 1, 2, 'tag', ''),
|
128
|
+
|
129
|
+
(3, 'favorite', '2020-03-00 00:00:00', 1, 3, 'user', 'jp'),
|
130
|
+
|
131
|
+
(4, 'favorite', '2020-04-00 00:00:00', 2, 5, 'user', 'jp'),
|
132
|
+
|
133
|
+
(5, 'favorite', '2020-05-00 00:00:00', 1, 7, 'comment', 'jp'),
|
134
|
+
|
135
|
+
(6, 'block', '2020-06-00 08:00:00', 1, 3, 'user', 'jp'),
|
136
|
+
|
137
|
+
(7, 'favorite', '2020-07-00 07:00:00', 1, 5, 'user', 'jp'),
|
138
|
+
|
139
|
+
(8, 'favorite', '2020-08-00 08:00:00', 1, 5, 'movie', 'en'),
|
140
|
+
|
141
|
+
(9, 'favorite', '2020-09-00 09:00:00', 1, 3, 'user', 'ko'),
|
142
|
+
|
143
|
+
(10, 'favorite', '2020-10-00 10:00:00', 1, 3, 'thread', 'jp'),
|
144
|
+
|
145
|
+
(11, 'follow', '2020-11-00 11:00:00', 1, 9, 'thread', 'jp')
|
146
|
+
|
147
|
+
;
|
148
|
+
|
149
|
+
|
150
|
+
|
151
|
+
# jp_contents
|
152
|
+
|
153
|
+
# jpのコンテンツのテーブル
|
154
|
+
|
155
|
+
CREATE TABLE jp_contents_table
|
156
|
+
|
157
|
+
(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)
|
158
|
+
|
159
|
+
;
|
160
|
+
|
161
|
+
INSERT INTO jp_contents_table
|
162
|
+
|
163
|
+
(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)
|
164
|
+
|
165
|
+
VALUES
|
166
|
+
|
167
|
+
(1, 0, '/1', '2020-01-00 00:00:00', 0, 0, 'en', 'drama', 'Mr.ROBOT', 0, '', ''),
|
168
|
+
|
169
|
+
(2, 3, '/2', '2020-02-00 00:00:00', 0, 0, 'jp', 'thread', '韓国の映画について語るスレ', 0, '', ''),
|
170
|
+
|
171
|
+
(3, 3, '/3', '2020-03-00 00:00:00', 0, 0, 'jp', 'thread', '米国の映画について語るスレ', 0, '', ''),
|
172
|
+
|
173
|
+
(4, 3, '/4', '2020-04-00 00:00:00', 3, 0, 'jp', 'comment', '米国のお勧め映画は何ですか?', 0, '', ''),
|
174
|
+
|
175
|
+
(5, 0, '/5', '2020-05-00 00:00:00', 0, 0, 'ko', 'manga', '지안', 0, '', ''),
|
176
|
+
|
177
|
+
(6, 1, '/6', '2020-06-00 00:00:00', 3, 4, 'jp', 'reply', '米国のMr.ROBOTを添付します。', 4, 'drama', 'en'),
|
178
|
+
|
179
|
+
(7, 4, '/7', '2020-07-00 00:00:00', 2, 0, 'jp', 'comment', '韓国の지안さんを添付します。', 3, 'user', 'ko'),
|
180
|
+
|
181
|
+
(8, 1, '/8', '2020-08-00 00:00:00', 3, 6, 'jp', 'reply', '面白そうですね。', 0, '', ''),
|
182
|
+
|
183
|
+
(9, 3, '/9', '2020-09-00 00:00:00', 3, 6, 'jp', 'reply', '良いですね。', 0, '', ''),
|
184
|
+
|
185
|
+
(10, 2, '/10', '2020-10-00 00:00:00', 3, 9, 'jp', 'reply', 'ええ、とても良いですよ。', 0, '', ''),
|
186
|
+
|
187
|
+
(11, 3, '/11', '2020-11-00 00:00:00', 0, 0, 'jp', 'thread', '日本の田中家について語るスレ', 0, '', ''),
|
188
|
+
|
189
|
+
(12, 1, '/12', '2020-12-00 00:00:00', 11, 0, 'jp', 'comment', '日本の三郎さんを添付します。', 3, 'user', 'jp'),
|
190
|
+
|
191
|
+
(13, 2, '/13', '2020-13-00 00:00:00', 2, 0, 'jp', 'comment', '米国の映画スレを添付します', 9, 'thread', 'jp'),
|
192
|
+
|
193
|
+
(14, 0, '/14', '2020-14-00 00:00:00', 0, 0, 'en', 'user', 'smith', 0, '', ''),
|
194
|
+
|
195
|
+
(15, 0, '/15', '2020-15-00 00:00:00', 0, 0, 'zh', 'manga', '砂輿海之歌', 0, '', ''),
|
196
|
+
|
197
|
+
(16, 0, '/16', '2020-16-00 00:00:00', 0, 0, 'en', 'movie', 'Avator', 0, '', ''),
|
198
|
+
|
199
|
+
(17, 0, '/17', '2020-17-00 00:00:00', 0, 0, 'ru', 'movie', 'Хардкор', 0, '', ''),
|
200
|
+
|
201
|
+
(18, 0, '/18', '2020-18-00 00:00:00', 0, 0, 'zh', 'drama', '大秦帝国', 0, '', '')
|
202
|
+
|
203
|
+
;
|
204
|
+
|
205
|
+
# jp_users
|
206
|
+
|
207
|
+
# ユーザーのテーブル
|
208
|
+
|
209
|
+
CREATE TABLE jp_users_table
|
210
|
+
|
211
|
+
(user_id int, unique_name text, nick_name text)
|
212
|
+
|
213
|
+
;
|
214
|
+
|
215
|
+
INSERT INTO jp_users_table
|
216
|
+
|
217
|
+
(user_id, unique_name, nick_name)
|
218
|
+
|
219
|
+
VALUES
|
220
|
+
|
221
|
+
(1, 'ichiro', '田中一郎'),
|
222
|
+
|
223
|
+
(2, 'jiro', '田中二郎'),
|
224
|
+
|
225
|
+
(3, 'saburo', '田中三郎'),
|
226
|
+
|
227
|
+
(4, 'shiro', '田中四郎'),
|
228
|
+
|
229
|
+
(5, 'goro', '山田五郎'),
|
230
|
+
|
231
|
+
(6, 'rokuro', '山田六郎'),
|
232
|
+
|
233
|
+
(7, 'nanaro', '山田七郎')
|
234
|
+
|
235
|
+
;
|
236
|
+
|
237
|
+
|
238
|
+
|
239
|
+
/*
|
240
|
+
|
241
|
+
■当SQLの概要
|
242
|
+
|
243
|
+
jp_contents_table から path='/7' を「対象」として取得します。
|
244
|
+
|
245
|
+
そして
|
26
246
|
|
27
247
|
「対象へのアクション日」
|
28
248
|
|
@@ -32,212 +252,10 @@
|
|
32
252
|
|
33
253
|
「対象の添付データへのアクション日」
|
34
254
|
|
35
|
-
という目的の取得は手探りながらも実装できたのですが、`jp_contents_table` テーブルは下図のように「対象へのアクション日」と「対象の添付データへのアクション日」で必要なので、そのあたりの処理が冗長に思えるのです。
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
スッキリさせる方法はございますでしょうか。
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
![![イメージ説明](f7775bef90d23dba95d42257cb1ab4d6.jpeg)
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
255
|
+
も併せて取得します
|
50
|
-
|
51
|
-
こちらがその冗長さを覚えるというソースコードです。
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
`jp_contents_table` テーブルから`path`のカラムが`/7`であるレコード(対象)を1件取得して、上図のように連結しています。
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
リンク先SQL fiddleにある
|
60
|
-
|
61
|
-
50行目の`# 「対象へのアクション日」をjoin`
|
62
|
-
|
63
|
-
89行目の`# 「対象の添付データへのアクション日」をjoin`
|
64
|
-
|
65
|
-
が`jp_contents_table` テーブルを2回呼んでいるという処理になります。
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
[下記のソースコードを実行する](http://sqlfiddle.com/#!9/062788/3)
|
72
|
-
|
73
|
-
```SQL
|
74
|
-
|
75
|
-
/*
|
76
|
-
|
77
|
-
■テーブルの構造
|
78
|
-
|
79
|
-
掲示板サイトのテーブルで、以下4つがあります。
|
80
|
-
|
81
|
-
・jp_actions_table : アクション
|
82
|
-
|
83
|
-
・jp_contents_table : コンテンツ
|
84
|
-
|
85
|
-
・jp_users _table : ユーザー
|
86
256
|
|
87
257
|
*/
|
88
258
|
|
89
|
-
|
90
|
-
|
91
|
-
# jp_actions
|
92
|
-
|
93
|
-
# アクションのテーブル
|
94
|
-
|
95
|
-
CREATE TABLE jp_actions_table
|
96
|
-
|
97
|
-
(action_id int, action_name text, action_date text, actor_id int, target_id int, target_type text, target_country_code text)
|
98
|
-
|
99
|
-
;
|
100
|
-
|
101
|
-
INSERT INTO jp_actions_table
|
102
|
-
|
103
|
-
(action_id, action_name, action_date, actor_id, target_id, target_type, target_country_code)
|
104
|
-
|
105
|
-
VALUES
|
106
|
-
|
107
|
-
(1, 'follow', '2020-01-00 00:00:00', 1, 2, 'user', 'jp'),
|
108
|
-
|
109
|
-
(2, 'follow', '2020-02-00 00:00:00', 1, 2, 'tag', ''),
|
110
|
-
|
111
|
-
(3, 'favorite', '2020-03-00 00:00:00', 1, 3, 'user', 'jp'),
|
112
|
-
|
113
|
-
(4, 'favorite', '2020-04-00 00:00:00', 2, 5, 'user', 'jp'),
|
114
|
-
|
115
|
-
(5, 'favorite', '2020-05-00 00:00:00', 1, 7, 'comment', 'jp'),
|
116
|
-
|
117
|
-
(6, 'block', '2020-06-00 08:00:00', 1, 3, 'user', 'jp'),
|
118
|
-
|
119
|
-
(7, 'favorite', '2020-07-00 07:00:00', 1, 5, 'user', 'jp'),
|
120
|
-
|
121
|
-
(8, 'favorite', '2020-08-00 08:00:00', 1, 5, 'movie', 'en'),
|
122
|
-
|
123
|
-
(9, 'favorite', '2020-09-00 09:00:00', 1, 3, 'user', 'ko'),
|
124
|
-
|
125
|
-
(10, 'favorite', '2020-10-00 10:00:00', 1, 3, 'thread', 'jp'),
|
126
|
-
|
127
|
-
(11, 'follow', '2020-11-00 11:00:00', 1, 9, 'thread', 'jp')
|
128
|
-
|
129
|
-
;
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
# jp_contents
|
134
|
-
|
135
|
-
# jpのコンテンツのテーブル
|
136
|
-
|
137
|
-
CREATE TABLE jp_contents_table
|
138
|
-
|
139
|
-
(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)
|
140
|
-
|
141
|
-
;
|
142
|
-
|
143
|
-
INSERT INTO jp_contents_table
|
144
|
-
|
145
|
-
(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)
|
146
|
-
|
147
|
-
VALUES
|
148
|
-
|
149
|
-
(1, 0, '/1', '2020-01-00 00:00:00', 0, 0, 'en', 'drama', 'Mr.ROBOT', 0, '', ''),
|
150
|
-
|
151
|
-
(2, 3, '/2', '2020-02-00 00:00:00', 0, 0, 'jp', 'thread', '韓国の映画について語るスレ', 0, '', ''),
|
152
|
-
|
153
|
-
(3, 3, '/3', '2020-03-00 00:00:00', 0, 0, 'jp', 'thread', '米国の映画について語るスレ', 0, '', ''),
|
154
|
-
|
155
|
-
(4, 3, '/4', '2020-04-00 00:00:00', 3, 0, 'jp', 'comment', '米国のお勧め映画は何ですか?', 0, '', ''),
|
156
|
-
|
157
|
-
(5, 0, '/5', '2020-05-00 00:00:00', 0, 0, 'ko', 'manga', '지안', 0, '', ''),
|
158
|
-
|
159
|
-
(6, 1, '/6', '2020-06-00 00:00:00', 3, 4, 'jp', 'reply', '米国のMr.ROBOTを添付します。', 4, 'drama', 'en'),
|
160
|
-
|
161
|
-
(7, 4, '/7', '2020-07-00 00:00:00', 2, 0, 'jp', 'comment', '韓国の지안さんを添付します。', 3, 'user', 'ko'),
|
162
|
-
|
163
|
-
(8, 1, '/8', '2020-08-00 00:00:00', 3, 6, 'jp', 'reply', '面白そうですね。', 0, '', ''),
|
164
|
-
|
165
|
-
(9, 3, '/9', '2020-09-00 00:00:00', 3, 6, 'jp', 'reply', '良いですね。', 0, '', ''),
|
166
|
-
|
167
|
-
(10, 2, '/10', '2020-10-00 00:00:00', 3, 9, 'jp', 'reply', 'ええ、とても良いですよ。', 0, '', ''),
|
168
|
-
|
169
|
-
(11, 3, '/11', '2020-11-00 00:00:00', 0, 0, 'jp', 'thread', '日本の田中家について語るスレ', 0, '', ''),
|
170
|
-
|
171
|
-
(12, 1, '/12', '2020-12-00 00:00:00', 11, 0, 'jp', 'comment', '日本の三郎さんを添付します。', 3, 'user', 'jp'),
|
172
|
-
|
173
|
-
(13, 2, '/13', '2020-13-00 00:00:00', 2, 0, 'jp', 'comment', '米国の映画スレを添付します', 9, 'thread', 'jp'),
|
174
|
-
|
175
|
-
(14, 0, '/14', '2020-14-00 00:00:00', 0, 0, 'en', 'user', 'smith', 0, '', ''),
|
176
|
-
|
177
|
-
(15, 0, '/15', '2020-15-00 00:00:00', 0, 0, 'zh', 'manga', '砂輿海之歌', 0, '', ''),
|
178
|
-
|
179
|
-
(16, 0, '/16', '2020-16-00 00:00:00', 0, 0, 'en', 'movie', 'Avator', 0, '', ''),
|
180
|
-
|
181
|
-
(17, 0, '/17', '2020-17-00 00:00:00', 0, 0, 'ru', 'movie', 'Хардкор', 0, '', ''),
|
182
|
-
|
183
|
-
(18, 0, '/18', '2020-18-00 00:00:00', 0, 0, 'zh', 'drama', '大秦帝国', 0, '', '')
|
184
|
-
|
185
|
-
;
|
186
|
-
|
187
|
-
# jp_users
|
188
|
-
|
189
|
-
# ユーザーのテーブル
|
190
|
-
|
191
|
-
CREATE TABLE jp_users_table
|
192
|
-
|
193
|
-
(user_id int, unique_name text, nick_name text)
|
194
|
-
|
195
|
-
;
|
196
|
-
|
197
|
-
INSERT INTO jp_users_table
|
198
|
-
|
199
|
-
(user_id, unique_name, nick_name)
|
200
|
-
|
201
|
-
VALUES
|
202
|
-
|
203
|
-
(1, 'ichiro', '田中一郎'),
|
204
|
-
|
205
|
-
(2, 'jiro', '田中二郎'),
|
206
|
-
|
207
|
-
(3, 'saburo', '田中三郎'),
|
208
|
-
|
209
|
-
(4, 'shiro', '田中四郎'),
|
210
|
-
|
211
|
-
(5, 'goro', '山田五郎'),
|
212
|
-
|
213
|
-
(6, 'rokuro', '山田六郎'),
|
214
|
-
|
215
|
-
(7, 'nanaro', '山田七郎')
|
216
|
-
|
217
|
-
;
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
/*
|
222
|
-
|
223
|
-
■当SQLの概要
|
224
|
-
|
225
|
-
jp_contents_table から path='/7' を「対象」として取得します。
|
226
|
-
|
227
|
-
そして
|
228
|
-
|
229
|
-
「対象へのアクション日」
|
230
|
-
|
231
|
-
「対象の投稿者」
|
232
|
-
|
233
|
-
「対象の添付データ」
|
234
|
-
|
235
|
-
「対象の添付データへのアクション日」
|
236
|
-
|
237
|
-
も併せて取得します
|
238
|
-
|
239
|
-
*/
|
240
|
-
|
241
259
|
select *
|
242
260
|
|
243
261
|
from (
|
@@ -468,39 +486,7 @@
|
|
468
486
|
|
469
487
|
```
|
470
488
|
|
471
|
-
|
489
|
+
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
「対象」との連結が81行目のこちらで、
|
476
|
-
|
477
|
-
`on base_action_record.target_id=t1.content_id`
|
478
|
-
|
479
|
-
そして「対象の添付データ」との連結が123行目のこちらになるので、
|
480
|
-
|
481
|
-
`on attach_action_record.target_id=base_record.attach_id`
|
482
|
-
|
483
|
-
これらの条件をまとめてかければと思いました。
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
しかし**”いずれか”**という下記のような書き方はあるものの、**”両方とも”**のような書き方が検索してもみつけられず、特に試したことといえるものもない状況です。
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
```SQL
|
492
|
-
|
493
|
-
on base_action_record.target_id=(case when 条件
|
494
|
-
|
495
|
-
then t1.content_id
|
496
|
-
|
497
|
-
else base_record.attach_id end);
|
498
|
-
|
499
|
-
```
|
500
|
-
|
501
|
-
別の発想が必要なのか、検索が足りないのかわかりませんが、もしお心当たりのある方、上記ソースコードをスッキリさせられる方がいらっしゃいましたらお力添え頂けましたら幸甚に存じます。
|
502
|
-
|
503
|
-
宜しくお願い致します。
|
504
490
|
|
505
491
|
|
506
492
|
|
1
画像添付など
test
CHANGED
File without changes
|
test
CHANGED
@@ -1,62 +1,74 @@
|
|
1
1
|
###前提
|
2
2
|
|
3
|
-
`jp_contents_table`
|
3
|
+
`jp_contents_table` テーブルから`path`のカラムが`/7`であるレコード(対象)を1件取得するSQLを書いています。
|
4
4
|
|
5
5
|
`path`のカラムの値は重複しないので必ず取得は1件です。
|
6
6
|
|
7
7
|
|
8
8
|
|
9
|
-
取得された「対象
|
9
|
+
取得された「対象」には、「添付データ」もありまして、それぞれに「アクション日」があります。
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
|
11
|
+
|
12
|
+
|
13
|
-
つまり、「対象
|
13
|
+
つまり、「対象」への「アクション日」や、「添付データ」への「アクション日」という具合です。
|
14
14
|
|
15
15
|
|
16
16
|
|
17
17
|
###質問
|
18
18
|
|
19
|
-
以下のソースコードでこの取得は手探りながらも実装できたのですが、知りたいことがございます。
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
「アクション日」
|
19
|
+
上のようにそれぞれの「アクション日」があるために`JOIN`させる`ON`が2通りあるのですが、その2通りのために`jp_contents_table` テーブルを2回呼んでいることにやや違和感を覚えています。これを改善したいです。
|
24
|
-
|
20
|
+
|
21
|
+
|
22
|
+
|
25
|
-
|
23
|
+
具体的には後述するソースコードで
|
24
|
+
|
26
|
-
|
25
|
+
「対象」
|
26
|
+
|
27
|
-
|
27
|
+
「対象へのアクション日」
|
28
|
+
|
28
|
-
|
29
|
+
「対象の投稿者」
|
30
|
+
|
31
|
+
「対象の添付データ」
|
32
|
+
|
33
|
+
「対象の添付データへのアクション日」
|
34
|
+
|
35
|
+
という目的の取得は手探りながらも実装できたのですが、`jp_contents_table` テーブルは下図のように「対象へのアクション日」と「対象の添付データへのアクション日」で必要なので、そのあたりの処理が冗長に思えるのです。
|
36
|
+
|
37
|
+
|
38
|
+
|
29
|
-
|
39
|
+
スッキリさせる方法はございますでしょうか。
|
30
|
-
|
31
|
-
|
32
|
-
|
40
|
+
|
41
|
+
|
42
|
+
|
33
|
-
|
43
|
+
![![イメージ説明](f7775bef90d23dba95d42257cb1ab4d6.jpeg)
|
44
|
+
|
45
|
+
|
34
46
|
|
35
47
|
|
36
48
|
|
37
49
|
###ソースコード
|
38
50
|
|
39
|
-
こちらが
|
51
|
+
こちらがその冗長さを覚えるというソースコードです。
|
40
|
-
|
41
|
-
|
42
|
-
|
52
|
+
|
53
|
+
|
54
|
+
|
43
|
-
`jp_contents_table`
|
55
|
+
`jp_contents_table` テーブルから`path`のカラムが`/7`であるレコード(対象)を1件取得して、上図のように連結しています。
|
44
56
|
|
45
57
|
|
46
58
|
|
47
59
|
リンク先SQL fiddleにある
|
48
60
|
|
49
|
-
|
61
|
+
50行目の`# 「対象へのアクション日」をjoin`
|
50
|
-
|
62
|
+
|
51
|
-
8
|
63
|
+
89行目の`# 「対象の添付データへのアクション日」をjoin`
|
52
|
-
|
64
|
+
|
53
|
-
が`
|
65
|
+
が`jp_contents_table` テーブルを2回呼んでいるという処理になります。
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
66
|
+
|
67
|
+
|
68
|
+
|
69
|
+
|
70
|
+
|
59
|
-
[下記のソースコードを実行する](http://sqlfiddle.com/#!9/
|
71
|
+
[下記のソースコードを実行する](http://sqlfiddle.com/#!9/062788/3)
|
60
72
|
|
61
73
|
```SQL
|
62
74
|
|
@@ -92,27 +104,27 @@
|
|
92
104
|
|
93
105
|
VALUES
|
94
106
|
|
95
|
-
(1, 'follow', '2020-01-0
|
107
|
+
(1, 'follow', '2020-01-00 00:00:00', 1, 2, 'user', 'jp'),
|
96
|
-
|
108
|
+
|
97
|
-
(2, 'follow', '2020-02-0
|
109
|
+
(2, 'follow', '2020-02-00 00:00:00', 1, 2, 'tag', ''),
|
98
|
-
|
110
|
+
|
99
|
-
(3, 'favorite', '2020-03-0
|
111
|
+
(3, 'favorite', '2020-03-00 00:00:00', 1, 3, 'user', 'jp'),
|
100
|
-
|
112
|
+
|
101
|
-
(4, 'favorite', '2020-04-0
|
113
|
+
(4, 'favorite', '2020-04-00 00:00:00', 2, 5, 'user', 'jp'),
|
102
|
-
|
114
|
+
|
103
|
-
(5, 'favorite', '2020-05-0
|
115
|
+
(5, 'favorite', '2020-05-00 00:00:00', 1, 7, 'comment', 'jp'),
|
104
|
-
|
116
|
+
|
105
|
-
(6, 'block', '2020-0
|
117
|
+
(6, 'block', '2020-06-00 08:00:00', 1, 3, 'user', 'jp'),
|
106
|
-
|
118
|
+
|
107
|
-
(7, 'favorite', '2020-07-0
|
119
|
+
(7, 'favorite', '2020-07-00 07:00:00', 1, 5, 'user', 'jp'),
|
108
|
-
|
120
|
+
|
109
|
-
(8, 'favorite', '2020-08-0
|
121
|
+
(8, 'favorite', '2020-08-00 08:00:00', 1, 5, 'movie', 'en'),
|
110
|
-
|
122
|
+
|
111
|
-
(9, 'favorite', '2020-09-0
|
123
|
+
(9, 'favorite', '2020-09-00 09:00:00', 1, 3, 'user', 'ko'),
|
112
|
-
|
124
|
+
|
113
|
-
(10, 'favorite', '2020-10-
|
125
|
+
(10, 'favorite', '2020-10-00 10:00:00', 1, 3, 'thread', 'jp'),
|
114
|
-
|
126
|
+
|
115
|
-
(11, 'follow', '2020-11-
|
127
|
+
(11, 'follow', '2020-11-00 11:00:00', 1, 9, 'thread', 'jp')
|
116
128
|
|
117
129
|
;
|
118
130
|
|
@@ -210,7 +222,7 @@
|
|
210
222
|
|
211
223
|
■当SQLの概要
|
212
224
|
|
213
|
-
jp_contents_table から path='/7' を「対象
|
225
|
+
jp_contents_table から path='/7' を「対象」として取得します。
|
214
226
|
|
215
227
|
そして
|
216
228
|
|
@@ -232,7 +244,7 @@
|
|
232
244
|
|
233
245
|
select
|
234
246
|
|
235
|
-
# 「対象
|
247
|
+
# 「対象」
|
236
248
|
|
237
249
|
t1.content_id
|
238
250
|
|
@@ -250,12 +262,20 @@
|
|
250
262
|
|
251
263
|
,t1.content_text
|
252
264
|
|
265
|
+
,t1.attach_id
|
266
|
+
|
267
|
+
,t1.attach_type
|
268
|
+
|
269
|
+
,t1.attach_country_code
|
270
|
+
|
253
271
|
# 「対象へのアクション日」
|
254
272
|
|
255
273
|
,base_action_record.follow_date
|
256
274
|
|
257
275
|
,base_action_record.favorite_date
|
258
276
|
|
277
|
+
,base_action_record.block_date
|
278
|
+
|
259
279
|
# 「対象の投稿者」
|
260
280
|
|
261
281
|
,case when t1.attach_country_code='jp' and t1.attach_type='user'
|
@@ -264,12 +284,6 @@
|
|
264
284
|
|
265
285
|
# 「対象の添付データ」
|
266
286
|
|
267
|
-
,t1.attach_id
|
268
|
-
|
269
|
-
,t1.attach_type
|
270
|
-
|
271
|
-
,t1.attach_country_code
|
272
|
-
|
273
287
|
,case when t1.attach_country_code='jp' and t1.attach_type='user'
|
274
288
|
|
275
289
|
then jp_u.nick_name else null end as attached_nick_name
|
@@ -362,16 +376,16 @@
|
|
362
376
|
|
363
377
|
) as base_action_record
|
364
378
|
|
379
|
+
|
380
|
+
|
381
|
+
on base_action_record.target_id=t1.content_id
|
382
|
+
|
383
|
+
and base_action_record.target_type=t1.content_type
|
384
|
+
|
385
|
+
and base_action_record.target_country_code=t1.country_code
|
386
|
+
|
365
387
|
|
366
388
|
|
367
|
-
on base_action_record.target_id=t1.content_id
|
368
|
-
|
369
|
-
and base_action_record.target_type=t1.content_type
|
370
|
-
|
371
|
-
and base_action_record.target_country_code=t1.country_code
|
372
|
-
|
373
|
-
|
374
|
-
|
375
389
|
# 取得をpathで指定(country_codeとcontent_typeにindexあり)
|
376
390
|
|
377
391
|
where t1.path='/7' and t1.country_code='jp' and t1.content_type='comment'
|
@@ -454,12 +468,42 @@
|
|
454
468
|
|
455
469
|
```
|
456
470
|
|
471
|
+
###試したこと
|
472
|
+
|
473
|
+
|
474
|
+
|
475
|
+
「対象」との連結が81行目のこちらで、
|
476
|
+
|
477
|
+
`on base_action_record.target_id=t1.content_id`
|
478
|
+
|
479
|
+
そして「対象の添付データ」との連結が123行目のこちらになるので、
|
480
|
+
|
481
|
+
`on attach_action_record.target_id=base_record.attach_id`
|
482
|
+
|
483
|
+
これらの条件をまとめてかければと思いました。
|
484
|
+
|
485
|
+
|
486
|
+
|
487
|
+
しかし**”いずれか”**という下記のような書き方はあるものの、**”両方とも”**のような書き方が検索してもみつけられず、特に試したことといえるものもない状況です。
|
488
|
+
|
489
|
+
|
490
|
+
|
491
|
+
```SQL
|
492
|
+
|
493
|
+
on base_action_record.target_id=(case when 条件
|
494
|
+
|
495
|
+
then t1.content_id
|
496
|
+
|
497
|
+
else base_record.attach_id end);
|
498
|
+
|
499
|
+
```
|
500
|
+
|
501
|
+
別の発想が必要なのか、検索が足りないのかわかりませんが、もしお心当たりのある方、上記ソースコードをスッキリさせられる方がいらっしゃいましたらお力添え頂けましたら幸甚に存じます。
|
502
|
+
|
503
|
+
宜しくお願い致します。
|
504
|
+
|
457
505
|
|
458
506
|
|
459
507
|
###補足情報(FW/ツールのバージョンなど)
|
460
508
|
|
461
509
|
phpMyAdmin(4.8.5)で、MySQL(10.0.33-MariaDB)を使っています。
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
効率的な方法がございましたら宜しくお願い致します。
|