質問編集履歴

11

SQLfiddleを修正

2020/02/17 22:31

投稿

ikatako
ikatako

スコア270

test CHANGED
File without changes
test CHANGED
@@ -16,7 +16,7 @@
16
16
 
17
17
 
18
18
 
19
- [下記のコードを実行する(SQLfiddle)](http://sqlfiddle.com/#!9/b0a45e/9)
19
+ [下記のコードを実行する(SQLfiddle)](http://sqlfiddle.com/#!9/b0a45e/10)
20
20
 
21
21
  ```SQL
22
22
 

10

SQLfiddleを修正

2020/02/17 22:31

投稿

ikatako
ikatako

スコア270

test CHANGED
File without changes
test CHANGED
@@ -16,7 +16,7 @@
16
16
 
17
17
 
18
18
 
19
- [下記のコードを実行する(SQLfiddle)](http://sqlfiddle.com/#!9/b0a45e/8)
19
+ [下記のコードを実行する(SQLfiddle)](http://sqlfiddle.com/#!9/b0a45e/9)
20
20
 
21
21
  ```SQL
22
22
 

9

SQLfiddleを修正

2020/02/17 22:30

投稿

ikatako
ikatako

スコア270

test CHANGED
File without changes
test CHANGED
@@ -16,7 +16,7 @@
16
16
 
17
17
 
18
18
 
19
- [下記のコードを実行する(SQLfiddle)](http://sqlfiddle.com/#!9/b0a45e/4)
19
+ [下記のコードを実行する(SQLfiddle)](http://sqlfiddle.com/#!9/b0a45e/8)
20
20
 
21
21
  ```SQL
22
22
 

8

SQLfiddleを追記

2020/02/17 22:29

投稿

ikatako
ikatako

スコア270

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

自己解決したため編集

2020/02/17 22:25

投稿

ikatako
ikatako

スコア270

test CHANGED
@@ -1 +1 @@
1
- こちら質問は現在編集中です
1
+ JOINONが違うとき、同じ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

編集中

2020/02/17 21:54

投稿

ikatako
ikatako

スコア270

test CHANGED
@@ -1 +1 @@
1
- SQLで、JOINONが異なる場合、JOINの内容が同じも2回書かないといけませんか?
1
+ こちら質問は現在編集中
test CHANGED
@@ -1,505 +1,3 @@
1
- ###前提
1
+ 質問が大変わかりにくかったため要点を絞るべく編集中です。
2
2
 
3
- `jp_contents_table`テーブルら`path`のカラムが`/7`であるレコード(対象)を1件取得するSQLを書いていま
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

誤字などの訂正

2020/02/17 20:14

投稿

ikatako
ikatako

スコア270

test CHANGED
@@ -1 +1 @@
1
- SQLで、JOINのONが異なる場合、同じテーブルでも2回呼ばければいけませんか?
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`と、「対象の添付データ」の`content_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

誤字などの訂正

2020/02/17 19:42

投稿

ikatako
ikatako

スコア270

test CHANGED
File without changes
test CHANGED
@@ -1,22 +1,22 @@
1
1
  ###前提
2
2
 
3
- `jp_contents_table` テーブルから`path`のカラムが`/7`であるレコード(対象)を1件取得するSQLを書いています。
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` テーブル2回呼んでいること(図の緑)にやや違和感を覚えています。これを改善したいです。
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
- 得たい結果は上図で、これは`user_id=1`さん(彼)が`path='/7'`のページ(対象)を閲覧している設定における取得結果です。
27
+ 得たい結果は上図レコードで、`user_id=1`さん(彼)が`path='/7'`のページ(対象)を閲覧している設定結果です。
28
-
29
-
30
-
28
+
29
+
30
+
31
- この取得が以下1~5のロジックでして、2と5で同じ`jp_actions_table`が呼ばれのですた、下記ソースコードに冗長さを覚えます。
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`で連結。(SQLfidleの50行目がこれです)
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`で連結。(SQLfidleの89行目がこれです)
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 fiddleにある
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

誤字などを修正

2020/02/17 17:16

投稿

ikatako
ikatako

スコア270

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

どういうロジックでどういう結果を得たいかを追記させて頂きました。

2020/02/17 17:02

投稿

ikatako
ikatako

スコア270

test CHANGED
File without changes
test CHANGED
@@ -16,13 +16,233 @@
16
16
 
17
17
  ###質問
18
18
 
19
- 上のようにそれぞれの「アクション日」があるために`JOIN`させる`ON`が2通りあるのですが、その2通りのために`jp_contents_table` テーブルを2回呼んでいることにやや違和感を覚えています。これを改善したいです。
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

画像添付など

2020/02/17 16:55

投稿

ikatako
ikatako

スコア270

test CHANGED
File without changes
test CHANGED
@@ -1,62 +1,74 @@
1
1
  ###前提
2
2
 
3
- `jp_contents_table` というテーブルから `path='/7'`レコードを1件取得するSQLを書いています。
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
- つまり、「対象のデータ」への`favorite`や、「添付データ」への`favorite`、という具合です。
13
+ つまり、「対象」への「アクション日」や、「添付データ」への「アクション日」という具合です。
14
14
 
15
15
 
16
16
 
17
17
  ###質問
18
18
 
19
- 以下のソースコードでこの取得は手探りながらも実装できたのですが、知りたいことがございます。
20
-
21
-
22
-
23
- 「アクション日」は`jp_actions`というテーブルから取得するのです、「対象のデータ」と`JOIN`させる`ON`と、「添付データ」との`JOIN`させる`ON`が異なるために`jp_actions`
19
+ 上のようにそれぞれの「アクション日」がために`JOIN`させる`ON`が2通りあのですが、その2通りのために`jp_contents_table` テーブルを2回呼んでいることにやや違和感を覚えています。これを改善したいです。
24
-
20
+
21
+
22
+
25
- を2回呼んでいすが、
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
- 同じテブルを2回呼ぶとなるとやや冗長に感じてしまうのですが、もしかしたらもっと良い方法などがございましたらご教示頂ければと思います。
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` というテーブルから `path='/7'`レコードを1件取得し、その投稿者やアクション日などを併せ取得できたのですが同じテーブルを2回というがどうしてもひっかかります。
55
+ `jp_contents_table` テーブルから`path`のカラムが`/7`であるレコード(対象)を1件取得して、上図に連結してます。
44
56
 
45
57
 
46
58
 
47
59
  リンク先SQL fiddleにある
48
60
 
49
- 49行目の`# 「対象へのアクション日」をjoin`
61
+ 50行目の`# 「対象へのアクション日」をjoin`
50
-
62
+
51
- 88行目の`# 「対象の添付データへのアクション日」をjoin`
63
+ 89行目の`# 「対象の添付データへのアクション日」をjoin`
52
-
64
+
53
- が`ON`以外は同じ処理で、`jp_actions`を2回呼んでいる部分になります。
65
+ が`jp_contents_table` テーブルを2回呼んでいるという処理になります。
54
-
55
-
56
-
57
-
58
-
66
+
67
+
68
+
69
+
70
+
59
- [下記のソースコードを実行する](http://sqlfiddle.com/#!9/b28f91/1)
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-01 01:00:00', 1, 2, 'user', 'jp'),
107
+ (1, 'follow', '2020-01-00 00:00:00', 1, 2, 'user', 'jp'),
96
-
108
+
97
- (2, 'follow', '2020-02-02 02:00:00', 1, 2, 'tag', ''),
109
+ (2, 'follow', '2020-02-00 00:00:00', 1, 2, 'tag', ''),
98
-
110
+
99
- (3, 'favorite', '2020-03-03 03:00:00', 1, 3, 'user', 'jp'),
111
+ (3, 'favorite', '2020-03-00 00:00:00', 1, 3, 'user', 'jp'),
100
-
112
+
101
- (4, 'favorite', '2020-04-04 04:00:00', 2, 5, 'user', 'jp'),
113
+ (4, 'favorite', '2020-04-00 00:00:00', 2, 5, 'user', 'jp'),
102
-
114
+
103
- (5, 'favorite', '2020-05-05 05:00:00', 1, 7, 'comment', 'jp'),
115
+ (5, 'favorite', '2020-05-00 00:00:00', 1, 7, 'comment', 'jp'),
104
-
116
+
105
- (6, 'block', '2020-08-08 08:00:00', 1, 3, 'user', 'jp'),
117
+ (6, 'block', '2020-06-00 08:00:00', 1, 3, 'user', 'jp'),
106
-
118
+
107
- (7, 'favorite', '2020-07-07 07:00:00', 1, 5, 'user', 'jp'),
119
+ (7, 'favorite', '2020-07-00 07:00:00', 1, 5, 'user', 'jp'),
108
-
120
+
109
- (8, 'favorite', '2020-08-08 08:00:00', 1, 5, 'movie', 'en'),
121
+ (8, 'favorite', '2020-08-00 08:00:00', 1, 5, 'movie', 'en'),
110
-
122
+
111
- (9, 'favorite', '2020-09-09 09:00:00', 1, 3, 'user', 'ko'),
123
+ (9, 'favorite', '2020-09-00 09:00:00', 1, 3, 'user', 'ko'),
112
-
124
+
113
- (10, 'favorite', '2020-10-10 10:00:00', 1, 3, 'thread', 'jp'),
125
+ (10, 'favorite', '2020-10-00 10:00:00', 1, 3, 'thread', 'jp'),
114
-
126
+
115
- (11, 'follow', '2020-11-11 11:00:00', 1, 9, 'thread', 'jp')
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
- 効率的な方法がございましたら宜しくお願い致します。