質問編集履歴

2

リンクと画像を微調整

2020/02/05 12:02

投稿

ikatako
ikatako

スコア270

test CHANGED
File without changes
test CHANGED
@@ -242,13 +242,13 @@
242
242
 
243
243
 
244
244
 
245
- [実行サンプル](http://sqlfiddle.com/#!9/2f19d3/46)
245
+ [実行サンプル](http://sqlfiddle.com/#!9/e2353/3)
246
246
 
247
247
 
248
248
 
249
249
  この実行サンプルの結果が下図で、緑が【問題➀】、赤が【問題➁】です。
250
250
 
251
- ![イメージ説明](e586e2a6b4e7d4b73bd7f6e3224e94cf.png)
251
+ ![イメージ説明](b10748172efa6e0cab1b7c7c3b32899d.png)
252
252
 
253
253
 
254
254
 

1

試しているうちに解決したことなどがあるので内容を大きく修正致しました

2020/02/05 12:02

投稿

ikatako
ikatako

スコア270

test CHANGED
File without changes
test CHANGED
@@ -1,52 +1,60 @@
1
1
  ###実現したいこと
2
2
 
3
- 後述するよに、下図の黄色いテーブルがある状況です。
3
+ `action_table`というテーブルに`favorite`というアクション記録されています。
4
-
4
+
5
- 図にあるように取得し、ピンク色テーブルのような「favoriteリストを作りたいです。
5
+ サイト閲覧者を`user_id=1`と仮定し、`favorite`リストを作りたいです。
6
-
7
-
8
-
9
- ![イメージ説明](3c5413eedc1903c017b9949937829461.jpeg)
10
-
11
-
12
-
13
- 特にネックになっているのは
14
-
15
-
16
-
17
- content_type=user && studio_name=own(自社ユーザー)の場合
18
-
19
- →`own_user_table`を元にしてピンク色のテーブルを作る。
20
-
21
-
22
-
23
- それ以外(自社ユーザー以外のコンテンツ)の場合
24
-
25
- →`content_table`を元にしてピンク色のテーブルを作る。
26
-
27
-
28
-
29
- という条件分岐です。
30
-
31
-
32
6
 
33
7
 
34
8
 
35
9
  ###発生している問題
36
10
 
37
- り上条件分岐うまくいかないという問題と
11
+ `favorite`リスト大体できたですが、
38
-
39
-
40
-
12
+
13
+
14
+
41
- あとは、follow_datefavorite_date、favorite_tagsなど`action_table`に属する値が取得できことが問題です
15
+ 【問題➀】`follow_date`と`favorite_date`が`null`ってしまうこと。
16
+
17
+ 【問題➁】「クジラの生活」の方だけ`favorite_tags`が取得できないこと。
18
+
19
+
20
+
21
+ が問題となっています。
42
22
 
43
23
 
44
24
 
45
25
  ###該当のテーブル
46
26
 
47
- こちらが上図の黄色いテーブルになります。
48
-
49
- 長くてすみませんが、SQL fiddleを後述してあるのでよろければそちらでご覧く
27
+ 長くてすみませんが、現在値として仮定た`CREATE TABLE`を掲載せて頂きます
28
+
29
+
30
+
31
+ テーブルは6つですが、大きく次の3つに分類されます。
32
+
33
+
34
+
35
+ |分類|テーブル名|
36
+
37
+ |:--|:--|
38
+
39
+ |『自社ユーザーが実行したアクション』|`action_table`|
40
+
41
+ |『自社ユーザー以外のコンテンツ』|`content_table`と`content_sub_table`|
42
+
43
+ |『自社ユーザー』|`own_user_table`と`own_user_sub_table`|
44
+
45
+
46
+
47
+
48
+
49
+ これらから`action_table`の`favorite`リストを作るわけですが、
50
+
51
+ `favorite`の対象が`target_type='user'`かつ`target_studio='own'`のときには『自社ユーザー』のテーブルを参照し、それ以外は『自社ユーザー以外のコンテンツ』を参照する予定です。
52
+
53
+
54
+
55
+ 以下`CREATE TABLE`です。
56
+
57
+
50
58
 
51
59
  ```SQL
52
60
 
@@ -66,8 +74,6 @@
66
74
 
67
75
  VALUES
68
76
 
69
- # サイト閲覧者としてuser_id=1を与え、彼のfavoriteリストを作りたい
70
-
71
77
  (1, 'follow', '2020-01-01 01:01:01', 1, 3, 'user', 'own', ''),
72
78
 
73
79
  (2, 'favorite', '2020-02-02 01:02:02', 1, 4, 'documentaly', 'nhk', '"["ドキュメンタリー","クジラ"]"'),
@@ -100,10 +106,6 @@
100
106
 
101
107
  VALUES
102
108
 
103
- # commentやnewsなど様々なcontent_typeが混在している
104
-
105
- # content_typeとcontent_textが欲しい
106
-
107
109
  (1, 'comment', 'こんにちは'),
108
110
 
109
111
  (2, 'review', 'まぁまぁ'),
@@ -134,10 +136,6 @@
134
136
 
135
137
  VALUES
136
138
 
137
- # content_typeに応じてこのサブ情報がそれぞれ異なるが
138
-
139
- # studio_nameとcontent_urlを取得したい
140
-
141
139
  (1, 1, 'studio_name', 'own'),
142
140
 
143
141
  (2, 1, 'content_url', 'own/comment/1'),
@@ -188,10 +186,6 @@
188
186
 
189
187
  VALUES
190
188
 
191
- # nick_nameをcontent_textとして取得して
192
-
193
- # unique_nameをcontent_text2として取得したい
194
-
195
189
  (1, 'ichiro', '田中一郎'),
196
190
 
197
191
  (2, 'jiro', '田中二郎'),
@@ -220,8 +214,6 @@
220
214
 
221
215
  VALUES
222
216
 
223
- # studio_nameとcontent_urlを取得したい
224
-
225
217
  (1, 1, 'studio_name', 'own'),
226
218
 
227
219
  (2, 1, 'content_url', 'own/user/ichiro'),
@@ -244,37 +236,127 @@
244
236
 
245
237
  ```
246
238
 
247
- ###試したこと 1/3
239
+ ###試したこと
248
-
240
+
249
- ず`own_user_table`か`content_table`かとう条件分岐をん無視して、`own_user_table`だけを対象としfavoriteリストを作ろうとしたのがこちらです。
241
+ この質問自体を大きく編集してしまいましたが、ろいろ試し経緯はぐちゃぐちゃとしているので次のコードまでたどり着いたという現状だけを掲載させ頂きます。
242
+
243
+
244
+
245
+ [実行サンプル](http://sqlfiddle.com/#!9/2f19d3/46)
246
+
247
+
248
+
249
+ この実行サンプルの結果が下図で、緑が【問題➀】、赤が【問題➁】です。
250
+
251
+ ![イメージ説明](e586e2a6b4e7d4b73bd7f6e3224e94cf.png)
252
+
253
+
254
+
255
+
250
256
 
251
257
  ```SQL
252
258
 
253
-
259
+ # user_id=1のfavoriteリストを取得するのが目標
260
+
254
-
261
+ /*
262
+
263
+ 発生している問題
264
+
265
+ 【問題➀】`follow_date`と`favorite_date`が`null`となってしまうこと。
266
+
267
+ 【問題➁】「クジラの生活」の方だけ`favorite_tags`が取得できないこと。
268
+
269
+ */
270
+
271
+ select
272
+
273
+ # 自社ユーザーかそうでないかで取得先テーブルを分岐
274
+
275
+ case
276
+
277
+ when content_type='user' and own_user_studio_name.sub_val='own'
278
+
255
- select own_user.user_id as mix_id
279
+ then own_user.user_id
280
+
256
-
281
+ else null
282
+
283
+ end as user_id,
284
+
285
+ case
286
+
287
+ when content_type='user' and own_user_studio_name.sub_val='own'
288
+
289
+ then null
290
+
291
+ else content.content_id
292
+
293
+ end as content_id,
294
+
295
+ case
296
+
297
+ when content_type='user' and own_user_studio_name.sub_val='own'
298
+
299
+ then own_user.nick_name
300
+
257
- , own_user.nick_name as content_text
301
+ else content.content_text
302
+
258
-
303
+ end as content_text,
304
+
305
+ case
306
+
307
+ when content_type='user' and own_user_studio_name.sub_val='own'
308
+
259
- , own_user.unique_name as content_text2
309
+ then own_user.unique_name
310
+
260
-
311
+ else null
312
+
261
- , content_url.sub_val as content_url
313
+ end as content_text2,
314
+
262
-
315
+ case
316
+
317
+ when content_type='user' and own_user_studio_name.sub_val='own'
318
+
319
+ then 'user'
320
+
321
+ else content_type
322
+
263
- , content_type as content_type
323
+ end as content_type,
324
+
264
-
325
+ case
326
+
327
+ when content_type='user' and own_user_studio_name.sub_val='own'
328
+
329
+ then own_user_content_url.sub_val
330
+
331
+ else content_content_url.sub_val
332
+
333
+ end as content_url,
334
+
335
+ case
336
+
337
+ when content_type='user' and own_user_studio_name.sub_val='own'
338
+
339
+ then own_user_studio_name.sub_val
340
+
341
+ else content_studio_name.sub_val
342
+
265
- , studio_name.sub_val as studio_name
343
+ end as studio_name,
344
+
345
+
346
+
266
-
347
+ # アクション情報を取得
348
+
267
- , his_favorite.follow_date
349
+ his_favorite.follow_date,
268
-
350
+
269
- , his_favorite.favorite_date
351
+ his_favorite.favorite_date,
270
-
352
+
271
- , his_favorite.favorite_tags
353
+ action.favorite_tags
272
-
273
-
354
+
355
+
274
356
 
275
357
  from (
276
358
 
277
- select favorite.*
359
+ select favorite.target_id
278
360
 
279
361
  , max(
280
362
 
@@ -294,9 +376,9 @@
294
376
 
295
377
  on favorite.actor_id=action.target_id
296
378
 
297
- and action.actor_id=1
379
+ and action.actor_id=1
298
-
380
+
299
- where favorite.actor_id=1
381
+ where favorite.actor_id=1 and favorite.action_name='favorite'
300
382
 
301
383
  and favorite.actor_id not in(
302
384
 
@@ -308,174 +390,68 @@
308
390
 
309
391
  )
310
392
 
311
- group by favorite.actor_id
393
+ group by favorite.target_id
312
394
 
313
395
  ) his_favorite
314
396
 
315
397
 
316
398
 
399
+ # アクション情報
400
+
401
+ left join action_table action
402
+
403
+ on his_favorite.target_id=action.action_id
404
+
405
+
406
+
407
+ # 自社ユーザー以外の情報
408
+
409
+ left join content_table content
410
+
411
+ on his_favorite.target_id=content.content_id
412
+
413
+ left join content_sub_table content_studio_name
414
+
415
+ on his_favorite.target_id=content_studio_name.content_id and content_studio_name.sub_key='studio_name'
416
+
417
+ left join content_sub_table content_content_url
418
+
419
+ on his_favorite.target_id=content_content_url.content_id and content_content_url.sub_key='content_url'
420
+
421
+
422
+
317
- # favorite情報
423
+ # 自社ユーザーの情報
318
424
 
319
425
  left join own_user_table own_user
320
426
 
321
- on his_favorite.target_id=own_user.user_id
427
+ on his_favorite.target_id=own_user.user_id
322
-
323
-
324
-
325
- # 自社ユーザー以外の情報
428
+
326
-
327
- left join content_table content
328
-
329
- on his_favorite.target_id=content.content_id
330
-
331
-
332
-
333
- # 自社ユーザー情報
334
-
335
- left join own_user_sub_table studio_name
429
+ left join own_user_sub_table own_user_studio_name
336
-
430
+
337
- on his_favorite.target_id=studio_name.user_id and studio_name.sub_key='studio_name'
431
+ on his_favorite.target_id=own_user_studio_name.user_id and own_user_studio_name.sub_key='studio_name'
338
-
432
+
339
- left join own_user_sub_table content_url
433
+ left join own_user_sub_table own_user_content_url
340
-
434
+
341
- on his_favorite.target_id=content_url.user_id and content_url.sub_key='content_url'
435
+ on his_favorite.target_id=own_user_content_url.user_id and own_user_content_url.sub_key='content_url'
342
-
436
+
343
- left join own_user_sub_table content_text
437
+ left join own_user_sub_table own_user_content_text
344
-
438
+
345
- on his_favorite.target_id=content_text.user_id and content_text.sub_key='content_text'
439
+ on his_favorite.target_id=own_user_content_text.user_id and own_user_content_text.sub_key='content_text'
346
440
 
347
441
  ```
348
442
 
349
- これを SQL fiddle で試したのが下図でして、赤枠の部分の
443
+
350
-
351
- `action_table`に属する値の取得がうまくいきません。
352
-
353
-
354
-
355
- [SQL fiddle で試す](http://sqlfiddle.com/#!9/248ea/5)
356
-
357
-
358
-
359
- ![イメージ説明](71b01b1b5898676349d23337dc47f446.png)
360
-
361
-
362
-
363
- ###試したこと 2/3
364
-
365
- そして上の問題は無視して条件分岐を実装しようと試みたのが下記コードになります。
366
-
367
- `case when then end`で「自社ユーザーの場合」という条件分岐を書けばできると考えたのですが。
368
-
369
- ```SQL
370
-
371
-
372
-
373
- select
374
-
375
-
376
-
377
- # 自社ユーザーの場合はown_user_tableから取得
378
-
379
- case when content_type='user' and studio_name='own' then
380
-
381
- own_user.user_id as mix_id
382
-
383
- , own_user.nick_name as content_text
384
-
385
- , own_user.unique_name as content_text2
386
-
387
- , content_url.sub_val as content_url
388
-
389
- , content_type as content_type,
390
-
391
- , studio_name.sub_val as studio_name
392
-
393
-
394
-
395
- # 自社ユーザー以外の場合はcontent_tableから取得
396
-
397
- else
398
-
399
- content.content_id as mix_id
400
-
401
- , content.content_text as content_text
402
-
403
- , '' as content_text2
404
-
405
- , content_url.sub_val as content_url
406
-
407
- , content_type as content_type,
408
-
409
- , studio_name.sub_val as studio_name
410
-
411
- end
412
-
413
-
414
-
415
- # いずれの場合もaction_tableから以下を取得
416
-
417
- , his_favorite.follow_date
418
-
419
- , his_favorite.favorite_date
420
-
421
- , his_favorite.favorite_tags
422
-
423
-
424
-
425
- from (
426
-
427
- /* 同上 */
428
-
429
- ```
430
-
431
- ###試したこと 3/3
432
-
433
- `case when then end`以外の条件分岐として`if end if`があるようで下記のように試しましたがこれもできずで、この時点で質問させて頂くことに致しました。
434
-
435
-
436
-
437
- 長いコードで大変申し訳ございませんが、どうぞ宜しくお願い致します
438
-
439
- ```SQL
440
-
441
-
442
-
443
- select
444
-
445
-
446
-
447
- # 自社ユーザーの場合はown_user_tableから取得
448
-
449
- if content_type='user' and studio_name='own'
450
-
451
- /* 同上 */
452
-
453
-
454
-
455
- # 自社ユーザー以外の場合はcontent_tableから取得
456
-
457
- else
458
-
459
- /* 同上 */
460
-
461
- end if
462
-
463
-
464
-
465
- # いずれの場合もaction_tableから以下を取得
466
-
467
- /* 同上 */
468
-
469
-
470
-
471
- from (
472
-
473
- /* 同上 */
474
-
475
- ```
476
444
 
477
445
  ###補足情報(FW/ツールのバージョンなど)
478
446
 
479
447
 
480
448
 
481
449
  phpMyAdmin(4.8.5)で、MySQL(10.0.33-MariaDB)を使っています。
450
+
451
+
452
+
453
+ SQL初心者がネットの見本などを参考に組み合わせたコードにつき、意味不明な部分などがあるかもしれませんがご容赦ください。
454
+
455
+
456
+
457
+ 宜しくお願い致します。