teratail header banner
teratail header banner
質問するログイン新規登録

質問編集履歴

11

SQLfiddleを修正

2020/02/17 22:31

投稿

ikatako
ikatako

スコア270

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/9)
10
+ [下記のコードを実行する(SQLfiddle)](http://sqlfiddle.com/#!9/b0a45e/10)
11
11
  ```SQL
12
12
  select *
13
13
  from (

10

SQLfiddleを修正

2020/02/17 22:31

投稿

ikatako
ikatako

スコア270

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/8)
10
+ [下記のコードを実行する(SQLfiddle)](http://sqlfiddle.com/#!9/b0a45e/9)
11
11
  ```SQL
12
12
  select *
13
13
  from (

9

SQLfiddleを修正

2020/02/17 22:30

投稿

ikatako
ikatako

スコア270

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/4)
10
+ [下記のコードを実行する(SQLfiddle)](http://sqlfiddle.com/#!9/b0a45e/8)
11
11
  ```SQL
12
12
  select *
13
13
  from (

8

SQLfiddleを追記

2020/02/17 22:29

投稿

ikatako
ikatako

スコア270

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

自己解決したため編集

2020/02/17 22:25

投稿

ikatako
ikatako

スコア270

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

編集中

2020/02/17 21:54

投稿

ikatako
ikatako

スコア270

title CHANGED
@@ -1,1 +1,1 @@
1
- SQLで、JOINONが異なる場合、JOINの内容が同じも2回書かないといけませんか?
1
+ こちら質問は現在編集中
body CHANGED
@@ -1,253 +1,2 @@
1
- ###前提
2
- `jp_contents_table`テーブルら`path`のカラムが`/7`であるレコード(対象)を1件取得するSQLを書いていま
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
- ![![イメージ説明](f7775bef90d23dba95d42257cb1ab4d6.jpeg)
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

誤字などの訂正

2020/02/17 20:14

投稿

ikatako
ikatako

スコア270

title CHANGED
@@ -1,1 +1,1 @@
1
- SQLで、JOINのONが異なる場合、同じテーブルでも2回呼ばければいけませんか?
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
  ![![イメージ説明](f7775bef90d23dba95d42257cb1ab4d6.jpeg)
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`と、「対象の添付データ」の`content_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

誤字などの訂正

2020/02/17 19:42

投稿

ikatako
ikatako

スコア270

title CHANGED
File without changes
body CHANGED
@@ -1,25 +1,25 @@
1
1
  ###前提
2
- `jp_contents_table` テーブルから`path`のカラムが`/7`であるレコード(対象)を1件取得するSQLを書いています。
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` テーブル2回呼んでいること(図の緑)にやや違和感を覚えています。これを改善したいです。
10
+ 上のようにそれぞれの「アクション日」があるために`JOIN`させる`ON`が2通りあるのですが、その2通りのために`jp_actions_table`テーブル2回同じ処理をしていること(図の緑)に違和感を覚えています。これを改善したいです。
11
11
 
12
12
  ![![イメージ説明](f7775bef90d23dba95d42257cb1ab4d6.jpeg)
13
13
 
14
- 得たい結果は上図で、これは`user_id=1`さん(彼)が`path='/7'`のページ(対象)を閲覧している設定における取得結果です。
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件取得
20
20
 
21
21
  2.「対象へのアクション日」を取得(図の緑)
22
- 彼が「対象」を`follow`した日が欲しい。そこで`jp_actions_table`から`action_date`を取得。そして`follow`対象である`target_id`と、「対象」の`content_id`で連結。(SQLfidleの50行目がこれです)
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`で連結。(SQLfidleの89行目がこれです)
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
- リンク先SQL fiddleにある
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

誤字などを修正

2020/02/17 17:16

投稿

ikatako
ikatako

スコア270

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
- 誰が対象を投稿したのかが欲しい。そこで`jp_content_table`の`author_id`と、`jp_users`の`user_id`で連結。
25
+ 誰が対象を投稿したのかが欲しい。そこで`jp_contents_table`の`author_id`と、`jp_users_table`の`user_id`で連結。
26
26
 
27
27
  4.「対象の添付データ」を取得(図の紫)
28
- 対象に添付データがあれば欲しいそこで`jp_content_table`の`attach_id`と、`jp_users`または`jp_content_table`で連結。
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

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

2020/02/17 17:02

投稿

ikatako
ikatako

スコア270

title CHANGED
File without changes
body CHANGED
@@ -7,21 +7,30 @@
7
7
  つまり、「対象」への「アクション日」や、「添付データ」への「アクション日」という具合です。
8
8
 
9
9
  ###質問
10
- 上のようにそれぞれの「アクション日」があるために`JOIN`させる`ON`が2通りあるのですが、その2通りのために`jp_contents_table` テーブルを2回呼んでいることにやや違和感を覚えています。これを改善したいです。
10
+ 上のようにそれぞれの「アクション日」があるために`JOIN`させる`ON`が2通りあるのですが、その2通りのために`jp_actions_table` テーブルを2回呼んでいること(図の緑)にやや違和感を覚えています。これを改善したいです。
11
11
 
12
- 具体的には後述するソースコードで
13
- 「対象」
14
- 「対象へのアクション日」
15
- 「対象の投稿者」
16
- 「対象の添付データ」
17
- 「対象の添付データへのアクション日」
18
- という目的の取得は手探りながらも実装できたのですが、`jp_contents_table` テブルは下図のように「対象へのアクション日」と「対象の添付データへのアクション日」で必要なので、そのあたりの処理が冗長に思えるのです。
12
+ ![![イメジ説明](f7775bef90d23dba95d42257cb1ab4d6.jpeg)
19
13
 
20
- スッキリさせる方法はござますでしょうか
14
+ 得た結果は上図、これは`user_id=1`さん(彼)が、`path='/7'`のページ(対象)を閲覧ている設定における取得結果です
21
15
 
22
- ![![イメー説明](f7775bef90d23dba95d42257cb1ab4d6.jpeg)
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
- が`jp_contents_table` テーブルを2回呼んでいるという処理になります。
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

画像添付など

2020/02/17 16:55

投稿

ikatako
ikatako

スコア270

title CHANGED
File without changes
body CHANGED
@@ -1,33 +1,39 @@
1
1
  ###前提
2
- `jp_contents_table` というテーブルから `path='/7'`レコードを1件取得するSQLを書いています。
2
+ `jp_contents_table` テーブルから`path`のカラムが`/7`であるレコード(対象)を1件取得するSQLを書いています。
3
3
  `path`のカラムの値は重複しないので必ず取得は1件です。
4
4
 
5
- 取得された「対象のデータ」には、「添付データ」もありまして、それぞれに「アクション日」があります。
5
+ 取得された「対象」には、「添付データ」もありまして、それぞれに「アクション日」があります。
6
6
 
7
- つまり、「対象のデータ」への`favorite`や、「添付データ」への`favorite`、という具合です。
7
+ つまり、「対象」への「アクション日」や、「添付データ」への「アクション日」という具合です。
8
8
 
9
9
  ###質問
10
- 以下ソースコードでこ取得は手探りならも実装できたのですが、りたいことがございます。
10
+ ようにそれぞれ「アクション日」あるめに`JOIN`させる`ON`が2通りあるのですが、その2通めに`jp_contents_table` テーブルを2回呼んでことにやや違和感を覚えています。これを改善したいです。
11
11
 
12
+ 具体的には後述するソースコードで
13
+ 「対象」
14
+ 「対象へのアクション日」
15
+ 「対象の投稿者」
16
+ 「対象の添付データ」
17
+ 「対象の添付データへのアクション日」
12
- 「アクション日」は`jp_actions`というテーブルから取得するのですが、「対象のデータ」と`JOIN`させる`ON`と、「添付データ」と`JOIN`させる`ON`が異、`jp_actions`
18
+ という目的の取得は手探りながらも実装できたのですが、`jp_contents_table` テーブルは下図のように「対象アクション日」と「対象の添付データアクション日」で必要ので、そのありの処理が冗長思えるのです。
13
- を2回呼んでいるのですが、
14
19
 
15
- これは仕のなことなのでしょうか。
20
+ スッキリさせる法はござますでしょうか。
16
21
 
17
- 同じテブルを2回呼ぶとなるとやや冗長に感じてしまうのですが、もしかしたらもっと良い方法などがございましたらご教示頂ければと思います。
22
+ ![![イメジ説明](f7775bef90d23dba95d42257cb1ab4d6.jpeg)
18
23
 
24
+
19
25
  ###ソースコード
20
- こちらが実装できたソースコードです。
26
+ こちらがその冗長さを覚えるというソースコードです。
21
27
 
22
- `jp_contents_table` というテーブルから `path='/7'`レコードを1件取得し、その投稿者やアクション日などを併せ取得できたのですが同じテーブルを2回というがどうしてもひっかかります。
28
+ `jp_contents_table` テーブルから`path`のカラムが`/7`であるレコード(対象)を1件取得して、上図に連結してます。
23
29
 
24
30
  リンク先SQL fiddleにある
25
- 49行目の`# 「対象へのアクション日」をjoin`
31
+ 50行目の`# 「対象へのアクション日」をjoin`
26
- 88行目の`# 「対象の添付データへのアクション日」をjoin`
32
+ 89行目の`# 「対象の添付データへのアクション日」をjoin`
27
- が`ON`以外は同じ処理で、`jp_actions`を2回呼んでいる部分になります。
33
+ が`jp_contents_table` テーブルを2回呼んでいるという処理になります。
28
34
 
29
35
 
30
- [下記のソースコードを実行する](http://sqlfiddle.com/#!9/b28f91/1)
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-01 01:00:00', 1, 2, 'user', 'jp'),
54
+ (1, 'follow', '2020-01-00 00:00:00', 1, 2, 'user', 'jp'),
49
- (2, 'follow', '2020-02-02 02:00:00', 1, 2, 'tag', ''),
55
+ (2, 'follow', '2020-02-00 00:00:00', 1, 2, 'tag', ''),
50
- (3, 'favorite', '2020-03-03 03:00:00', 1, 3, 'user', 'jp'),
56
+ (3, 'favorite', '2020-03-00 00:00:00', 1, 3, 'user', 'jp'),
51
- (4, 'favorite', '2020-04-04 04:00:00', 2, 5, 'user', 'jp'),
57
+ (4, 'favorite', '2020-04-00 00:00:00', 2, 5, 'user', 'jp'),
52
- (5, 'favorite', '2020-05-05 05:00:00', 1, 7, 'comment', 'jp'),
58
+ (5, 'favorite', '2020-05-00 00:00:00', 1, 7, 'comment', 'jp'),
53
- (6, 'block', '2020-08-08 08:00:00', 1, 3, 'user', 'jp'),
59
+ (6, 'block', '2020-06-00 08:00:00', 1, 3, 'user', 'jp'),
54
- (7, 'favorite', '2020-07-07 07:00:00', 1, 5, 'user', 'jp'),
60
+ (7, 'favorite', '2020-07-00 07:00:00', 1, 5, 'user', 'jp'),
55
- (8, 'favorite', '2020-08-08 08:00:00', 1, 5, 'movie', 'en'),
61
+ (8, 'favorite', '2020-08-00 08:00:00', 1, 5, 'movie', 'en'),
56
- (9, 'favorite', '2020-09-09 09:00:00', 1, 3, 'user', 'ko'),
62
+ (9, 'favorite', '2020-09-00 09:00:00', 1, 3, 'user', 'ko'),
57
- (10, 'favorite', '2020-10-10 10:00:00', 1, 3, 'thread', 'jp'),
63
+ (10, 'favorite', '2020-10-00 10:00:00', 1, 3, 'thread', 'jp'),
58
- (11, 'follow', '2020-11-11 11:00:00', 1, 9, 'thread', 'jp')
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
- 効率的な方法がございましたら宜しくお願い致します。