質問編集履歴

3

my_commentsのCREATEを修正

2022/04/28 07:34

投稿

nikuatsu
nikuatsu

スコア177

test CHANGED
File without changes
test CHANGED
@@ -16,15 +16,16 @@
16
16
  ```SQL
17
17
  -- コメント
18
18
  CREATE TABLE my_comments(
19
- `ID` int, `lang_id` int, `comment` varchar(10),
19
+ `ID` int, `lang_id` int, `comment` varchar(10), count_likes int(10),
20
- PRIMARY KEY (`ID`) );
20
+ PRIMARY KEY (`ID`),
21
+ FULLTEXT full_my_comments (`comment`) WITH PARSER ngram );
21
22
  INSERT INTO my_comments
22
- (`ID`, `lang_id`, `comment`)
23
+ (`ID`, `lang_id`, `comment`, `count_likes`)
23
24
  VALUES
24
- (1, 1, '眠らないでください'),
25
+ (1, 1, '眠らないでください', 5),
25
- (2, 1, '静かにしてください'),
26
+ (2, 1, '静かにしてください', 1),
26
- (3, 1, '席についてください'),
27
+ (3, 1, '席についてください', 6),
27
- (4, 1, 'たまに休んで下さい');
28
+ (4, 1, 'たまに休んで下さい', 9);
28
29
 
29
30
  -- タグ
30
31
  CREATE TABLE my_tags(

2

文章の構成を修正

2022/04/23 02:53

投稿

nikuatsu
nikuatsu

スコア177

test CHANGED
File without changes
test CHANGED
@@ -1,15 +1,18 @@
1
1
  ### 実現したいこと
2
- `GROUP_CONCAT`を省略できるような`SELECT`記述方法探してす。
2
+ 以下のCREATE、INSERTから、次結果得たす。
3
-
4
- ### 発生している問題
5
- 後のPHPの`set_tag_datas_to_row()`で最終的に求めている値を得るために、次の`SELECT`を実行しています。
6
-
7
- 特に`GROUP_CONCAT`は「 tag_kind_id の値の数 ✕ カラムの数 」なので、次の`SELECT`では6つです。
8
-
9
- しかし実際にtag_kind_id もカラムももっとたくさんあり、6どころではなく長大なSQL文になってまのが問題です。
3
+ これ'指導' のタグを持コメントを取得た結果です。
4
+
10
-
5
+ ```SQL
6
+ +----+----------------------+---------------------+--------------------------+-----------------+--------------------+---------------+
7
+ | ID | author_tag_names | author_is_officials | author_details | genre_tag_names | genre_is_officials | genre_details |
8
+ +----+----------------------+---------------------+--------------------------+-----------------+--------------------+---------------+
9
+ | 1 | 鈴木__SEPARATOR__佐藤 | 1__SEPARATOR__0 | 良い人__SEPARATOR__悪い人 | 指導 | 1 | . |
10
+ +----+----------------------+---------------------+--------------------------+-----------------+--------------------+---------------+
11
+ | 3 | NULL | NULL | NULL | 指導 | 1 | . |
12
+ +----+----------------------+---------------------+--------------------------+-----------------+--------------------+---------------+
13
+ ```
14
+
11
- ### 該当のソースコード
15
+ ### CREATE、INSERT
12
- まずSQLで対象データの例です。
13
16
  ```SQL
14
17
  -- コメント
15
18
  CREATE TABLE my_comments(
@@ -46,11 +49,15 @@
46
49
  (2, 4),
47
50
  (3, 3);
48
51
  ```
49
-
52
+ ### 実現するための自分なりのSELECT
50
- の対象データから次の`SELECT`で目的のレコードを取得てきます。が`GROUP_CONCAT`が多すぎて速度が遅くなることを問題視います。
53
+ 自分でれを実現する場合は次のSELECTしか書けず、GROUP_CONCAT が多すぎてしいます。
54
+
55
+ ご覧のように「GROUP_CONCAT の回数」は、「 tag_kind_id の値の数 ✕ カラムの数 」という2つで構想されているので、次のSELECTでは6回になっています…
56
+
57
+ …が、実際にはこの2つはもっと多いので GROUP_CONCAT だらけ(50回くらい)になってしまい、速度が遅くなるのです。
58
+
51
59
  ```SQL
52
- -- タグ名を指定して検索
53
- -- GROUP_CONCAT が多すぎる!!
60
+ -- '指導' で検索した結果を取得
54
61
  SELECT
55
62
  comments.ID
56
63
 
@@ -117,15 +124,17 @@
117
124
 
118
125
  -- タグ名を指定
119
126
  WHERE
120
- tags2.tag_name = '指導' # '指導'で検索された場合
127
+ tags2.tag_name = '指導'
121
128
  GROUP BY comments.ID
122
129
  LIMIT 0, 5
123
130
 
124
131
  ```
132
+
133
+ ### 補足
125
- 最後にSQLで取得したレコードに、PHPで次の`set_tag_datas_to_row()`をかけて、この`$result`が最終的にフロントへ出力する値として求めるものになります。
134
+ ちなみSELECTの結果、PHPで次の`set_tag_datas_to_row()`をかけて、この`$result`が最終的にフロントへ出力する値として求めるものになります。
126
135
  ```PHP
127
136
  <?php
128
- // SQLで取得したレコード
137
+ // SELECTの結果
129
138
  $rows = [
130
139
  ['ID'=>1,
131
140
  'author_tag_names'=>'鈴木__SEPARATOR__佐藤','author_is_officials'=>'1__SEPARATOR__0','author_details'=>'良い人__SEPARATOR__悪い人',
@@ -182,7 +191,7 @@
182
191
  )
183
192
  */
184
193
 
185
- // レコード tag_datas をセット
194
+ // SELECTの結果tag_datas をセット
186
195
  function set_tag_datas_to_row( $row ){
187
196
  $result = [];
188
197
 
@@ -226,48 +235,6 @@
226
235
 
227
236
  ```
228
237
 
229
- ### 試したこと
230
- 通常の`CASE~WHEN~THEN`は次のようになりますが、
231
- ```SQL
232
- CASE
233
- WHEN 条件1 THEN カラムAの値
234
- ELSE その他の値
235
- END
236
- ```
237
- 次のように複数の値を指定できればいいなと思いました。
238
- ```SQL
239
- CASE
240
- WHEN 条件1 THEN カラムAの値, カラムBの値
241
- ELSE その他の値
242
- END
243
- ```
244
- もしこのように指定できれば、先ほど提示した次のSQLは、
245
- ```SQL
246
- # tag_kind_id=1 の tag_name
247
- ,GROUP_CONCAT(
248
- CASE WHEN tags.tag_kind_id=1
249
- THEN tags.tag_name
250
- ELSE null END
251
- ) AS author_tag_names
252
-
253
- # tag_kind_id=1 の is_official
254
- ,GROUP_CONCAT(
255
- CASE WHEN tags.tag_kind_id=1
256
- THEN tags.is_official
257
- ELSE null END
258
- ) AS author_is_officials
259
- ```
260
-
261
- 次のように省略できますので、`GROUP_CONCAT`の数を「 tag_kind_id の値の数 ✕ カラムの数」ではなく「 tag_kind_id の値の数」にできると踏んだのですが…
262
- ```SQL
263
- # tag_kind_id=1 の 各カラムの値
264
- ,GROUP_CONCAT(
265
- CASE WHEN tags.tag_kind_id=1
266
- THEN tags.tag_name, tags.is_official, tags.detail
267
- ELSE null END
268
- ) AS author_datas
269
-
270
- ```
271
238
  CREATE、INSERT、$result 以外は変えてしまって構いません。
272
239
  この多すぎる`GROUP_CONCAT`をなんとか省略する方法を知りたいです。
273
240
  宜しくお願いいたします。

1

SQL文を一部訂正

2022/04/22 10:30

投稿

nikuatsu
nikuatsu

スコア177

test CHANGED
File without changes
test CHANGED
@@ -263,7 +263,7 @@
263
263
  # tag_kind_id=1 の 各カラムの値
264
264
  ,GROUP_CONCAT(
265
265
  CASE WHEN tags.tag_kind_id=1
266
- THEN tags.tag_name, tags.is_official
266
+ THEN tags.tag_name, tags.is_official, tags.detail
267
267
  ELSE null END
268
268
  ) AS author_datas
269
269