質問編集履歴
7
行番号を汎用的に変更
test
CHANGED
@@ -1 +1 @@
|
|
1
|
-
UNIONする場合だけ、厳密なGROUP BYが要求される理由
|
1
|
+
UNION する場合だけ、厳密な GROUP BY が要求される理由
|
test
CHANGED
@@ -9,6 +9,7 @@
|
|
9
9
|
なぜ➂の場合だけ、SELECTするカラムすべてにGROUP BYを付けなければエラーになるのか?理由を知りたいです。
|
10
10
|
|
11
11
|
### CREATE、INSERT
|
12
|
+
対象レコードです。
|
12
13
|
```SQL
|
13
14
|
-- コメント
|
14
15
|
CREATE TABLE my_comments(
|
@@ -48,18 +49,18 @@
|
|
48
49
|
```
|
49
50
|
|
50
51
|
### ➀:「コメントの本文」をSELECT
|
51
|
-
まずこちらは、
|
52
|
+
まずこちらは、`# ➀-1`から`# ➀-2`行目の5つのカラムに対し、`# ➀-3`行目で「IDだけでまとめる」よう指定していますが、エラーは起こりません。
|
52
53
|
```SQL
|
53
54
|
-- ➀:「コメントの本文」をSELECT
|
54
55
|
SELECT
|
55
|
-
comments.ID AS comment_id -
|
56
|
+
comments.ID AS comment_id # ➀-1
|
56
57
|
,comments.lang_id
|
57
58
|
,comments.comment
|
58
59
|
,comments.count_likes
|
59
60
|
,GROUP_CONCAT(
|
60
61
|
tags.ID
|
61
62
|
SEPARATOR '__SEPARATOR__'
|
62
|
-
) AS tag_ids -
|
63
|
+
) AS tag_ids # ➀-2
|
63
64
|
|
64
65
|
FROM
|
65
66
|
my_comments comments
|
@@ -71,24 +72,24 @@
|
|
71
72
|
-- '指導'を持つコメントを指定
|
72
73
|
WHERE MATCH (comments.comment) AGAINST ('指導' IN BOOLEAN MODE)
|
73
74
|
|
74
|
-
GROUP BY comments.ID -
|
75
|
+
GROUP BY comments.ID # ➀-3
|
75
76
|
ORDER BY comments.count_likes DESC, comments.ID DESC
|
76
77
|
LIMIT 0, 20
|
77
78
|
```
|
78
79
|
|
79
80
|
### ②:「コメントについたタグ」をSELECT
|
80
|
-
またこちらは、
|
81
|
+
またこちらは、`# ➁-1`から`# ➁-2`行目の5つのカラムに対し、`# ➁-3`行目で「IDだけでまとめる」よう指定していますが、エラーは起こりません。
|
81
82
|
```SQL
|
82
83
|
-- ➁:「コメントについたタグ」をSELECT
|
83
84
|
SELECT
|
84
|
-
comments.ID AS comment_id -
|
85
|
+
comments.ID AS comment_id # ➁-1
|
85
86
|
,comments.lang_id
|
86
87
|
,comments.comment
|
87
88
|
,comments.count_likes
|
88
89
|
,GROUP_CONCAT(
|
89
90
|
tags.ID
|
90
91
|
SEPARATOR '__SEPARATOR__'
|
91
|
-
) AS tag_ids -
|
92
|
+
) AS tag_ids # ➁-2
|
92
93
|
|
93
94
|
FROM
|
94
95
|
my_comments comments
|
@@ -106,16 +107,21 @@
|
|
106
107
|
-- '指導'を持つタグを指定
|
107
108
|
WHERE tags2.tag_name LIKE '%指導%'
|
108
109
|
|
109
|
-
GROUP BY comments.ID -
|
110
|
+
GROUP BY comments.ID # ➁-3
|
110
111
|
ORDER BY comments.count_likes DESC, comments.ID DESC
|
111
112
|
LIMIT 0, 20
|
112
113
|
```
|
113
114
|
|
114
115
|
### ➂: ➀と➁をUNIONしてSELECT
|
115
|
-
疑問なのがこちらで、➀と➁と同じ5つのカラムに対し、同じように
|
116
|
+
疑問なのがこちらで、➀と➁と同じように`# ➂-1`から`# ➂-2`行目の5つのカラムに対し、同じように`# ➂-3`行目で「comment_idだけでまとめる」よう指定しているつもりなのですが、この場合にエラーになります。
|
116
117
|
```SQL
|
117
118
|
-- ➂: ➀と➁をUNIONしてSELECT
|
118
|
-
SELECT
|
119
|
+
SELECT
|
120
|
+
x.comment_id # ➂-1
|
121
|
+
,x.lang_id
|
122
|
+
,x.comment
|
123
|
+
,x.count_likes
|
124
|
+
,x.tag_ids # ➂-2
|
119
125
|
FROM (
|
120
126
|
(
|
121
127
|
|
@@ -127,9 +133,9 @@
|
|
127
133
|
-- ➁:「コメントについたタグ」をSELECT
|
128
134
|
-- 上と同じなので割愛
|
129
135
|
)
|
130
|
-
)x
|
136
|
+
) AS x
|
131
137
|
|
132
|
-
GROUP BY x.comment_id -
|
138
|
+
GROUP BY x.comment_id # ➂-3
|
133
139
|
ORDER BY x.count_likes DESC, x.comment_id DESC
|
134
140
|
LIMIT 0, 20
|
135
141
|
```
|
6
環境にサーバーを追加
test
CHANGED
File without changes
|
test
CHANGED
@@ -161,7 +161,8 @@
|
|
161
161
|
|
162
162
|
言い換えるなら、③でSELECTするカラムすべてにGROUP BYを付けなければエラーになるのならば、➀➁だって`GROUP BY comments.ID`だけではエラーになるハズではないか?という疑問になります。
|
163
163
|
|
164
|
-
###
|
164
|
+
### 環境
|
165
|
+
サーバー:ConoHa WING
|
165
|
-
phpMyAdmin:
|
166
|
+
phpMyAdmin:5.1.3-2.el7.remi
|
166
|
-
MySQL:
|
167
|
+
MySQL:5.7.27-log
|
167
168
|
|
5
誤字などの修正
test
CHANGED
File without changes
|
test
CHANGED
@@ -135,7 +135,7 @@
|
|
135
135
|
```
|
136
136
|
|
137
137
|
### エラーメッセージ
|
138
|
-
③
|
138
|
+
③の場合のエラーがこちらです。(改行は質問者が追加)
|
139
139
|
|
140
140
|
```SQL
|
141
141
|
#1055 - Expression #2 of SELECT list is not in GROUP BY clause
|
@@ -155,7 +155,7 @@
|
|
155
155
|
```
|
156
156
|
さらに、`SELECT @@global.sql_mode;`で確認される`ONLY_FULL_GROUP_BY`を解除すると、`GROUP BY x.comment_id`のままでもエラー解消できました。
|
157
157
|
|
158
|
-
これらのことから、➀➁
|
158
|
+
これらのことから、➀➁で平気で、③がエラーになるその違いはGROUP BYに由来するものだと考えられます。
|
159
159
|
|
160
160
|
でも私は➀➁③どれもが、『同じカラムに対して同じようにGROUP BYしている認識』なのですが、UNIONした場合は何が異なるのでしょうか?
|
161
161
|
|
4
「:」を追加
test
CHANGED
File without changes
|
test
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
### 前提
|
2
2
|
➀と➁をSELECTする場合はIDだけにGROUP BYを付ければいいのですが、➂でUNIONする場合はSELECTするカラムすべてにGROUP BYを付けなければエラーになります。
|
3
3
|
|
4
|
-
➀「コメントの本文」をSELECT
|
4
|
+
➀:「コメントの本文」をSELECT
|
5
|
-
➁「コメントについたタグ」をSELECT
|
5
|
+
➁:「コメントについたタグ」をSELECT
|
6
|
-
➂ ➀と②をUNIONしてSELECT
|
6
|
+
➂: ➀と②をUNIONしてSELECT
|
7
7
|
|
8
8
|
### 知りたいこと
|
9
9
|
なぜ➂の場合だけ、SELECTするカラムすべてにGROUP BYを付けなければエラーになるのか?理由を知りたいです。
|
@@ -47,10 +47,10 @@
|
|
47
47
|
(3, 3);
|
48
48
|
```
|
49
49
|
|
50
|
-
### ➀「コメントの本文」をSELECT
|
50
|
+
### ➀:「コメントの本文」をSELECT
|
51
51
|
まずこちらは、3行目から10行目の5つのカラムに対し、22行目で「IDだけでまとめる」よう指定していますが、エラーなく取得できます。
|
52
52
|
```SQL
|
53
|
-
-- ➀「コメントの本文」をSELECT
|
53
|
+
-- ➀:「コメントの本文」をSELECT
|
54
54
|
SELECT
|
55
55
|
comments.ID AS comment_id -- 3行目
|
56
56
|
,comments.lang_id
|
@@ -76,10 +76,10 @@
|
|
76
76
|
LIMIT 0, 20
|
77
77
|
```
|
78
78
|
|
79
|
-
### ②「コメントについたタグ」をSELECT
|
79
|
+
### ②:「コメントについたタグ」をSELECT
|
80
80
|
またこちらは、3行目から10行目の5つのカラムに対し、28行目で「IDだけでまとめる」よう指定していますが、エラーなく取得できます。
|
81
81
|
```SQL
|
82
|
-
-- ➁「コメントについたタグ」をSELECT
|
82
|
+
-- ➁:「コメントについたタグ」をSELECT
|
83
83
|
SELECT
|
84
84
|
comments.ID AS comment_id -- 3行目
|
85
85
|
,comments.lang_id
|
@@ -111,20 +111,20 @@
|
|
111
111
|
LIMIT 0, 20
|
112
112
|
```
|
113
113
|
|
114
|
-
### ➂ ➀と➁をUNIONしてSELECT
|
114
|
+
### ➂: ➀と➁をUNIONしてSELECT
|
115
115
|
疑問なのがこちらで、➀と➁と同じ5つのカラムに対し、同じように66行目で「comment_idだけでまとめる」よう指定しているつもりなのですが、この場合にエラーになります。
|
116
116
|
```SQL
|
117
|
-
-- ➂ ➀と➁をUNIONしてSELECT
|
117
|
+
-- ➂: ➀と➁をUNIONしてSELECT
|
118
118
|
SELECT *
|
119
119
|
FROM (
|
120
120
|
(
|
121
121
|
|
122
|
-
-- ➀「コメントの本文」をSELECT
|
122
|
+
-- ➀:「コメントの本文」をSELECT
|
123
123
|
-- 上と同じなので割愛
|
124
124
|
|
125
125
|
) UNION (
|
126
126
|
|
127
|
-
-- ➁「コメントについたタグ」をSELECT
|
127
|
+
-- ➁:「コメントについたタグ」をSELECT
|
128
128
|
-- 上と同じなので割愛
|
129
129
|
)
|
130
130
|
)x
|
3
疑問を加筆
test
CHANGED
File without changes
|
test
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
### 前提
|
2
|
-
➀と➁をSELECTする場合はIDだけにGROUP BYを付ければいいのですが、➂でUNIONする場合はSELECTするカラムすべてにGROUP BYを付けなければ
|
2
|
+
➀と➁をSELECTする場合はIDだけにGROUP BYを付ければいいのですが、➂でUNIONする場合はSELECTするカラムすべてにGROUP BYを付けなければエラーになります。
|
3
3
|
|
4
4
|
➀「コメントの本文」をSELECT
|
5
5
|
➁「コメントについたタグ」をSELECT
|
6
6
|
➂ ➀と②をUNIONしてSELECT
|
7
7
|
|
8
8
|
### 知りたいこと
|
9
|
-
なぜ➂の場合だけ、SELECTするカラムすべてにGROUP BYを付けなければ
|
9
|
+
なぜ➂の場合だけ、SELECTするカラムすべてにGROUP BYを付けなければエラーになるのか?理由を知りたいです。
|
10
10
|
|
11
11
|
### CREATE、INSERT
|
12
12
|
```SQL
|
@@ -159,6 +159,8 @@
|
|
159
159
|
|
160
160
|
でも私は➀➁③どれもが、『同じカラムに対して同じようにGROUP BYしている認識』なのですが、UNIONした場合は何が異なるのでしょうか?
|
161
161
|
|
162
|
+
言い換えるなら、③でSELECTするカラムすべてにGROUP BYを付けなければエラーになるのならば、➀➁だって`GROUP BY comments.ID`だけではエラーになるハズではないか?という疑問になります。
|
163
|
+
|
162
164
|
### ツールのバージョン
|
163
165
|
phpMyAdmin:`5.1.3-2.el7.remi`
|
164
166
|
MySQL:`5.7.27-log`
|
2
コードの同じ部分を割愛
test
CHANGED
File without changes
|
test
CHANGED
@@ -120,62 +120,12 @@
|
|
120
120
|
(
|
121
121
|
|
122
122
|
-- ➀「コメントの本文」をSELECT
|
123
|
-
SELECT
|
124
|
-
comments.ID AS comment_id
|
125
|
-
,comments.lang_id
|
126
|
-
,comments.comment
|
127
|
-
,comments.count_likes
|
128
|
-
,GROUP_CONCAT(
|
129
|
-
tags.ID
|
130
|
-
SEPARATOR '__SEPARATOR__'
|
131
|
-
|
123
|
+
-- 上と同じなので割愛
|
132
|
-
|
133
|
-
FROM
|
134
|
-
my_comments comments
|
135
|
-
LEFT JOIN my_tag_holders th
|
136
|
-
ON th.comments_ID = comments.ID
|
137
|
-
LEFT JOIN my_tags tags
|
138
|
-
ON tags.ID = th.tags_ID
|
139
|
-
|
140
|
-
-- '指導'を持つコメントを指定
|
141
|
-
WHERE MATCH (comments.comment) AGAINST ('指導' IN BOOLEAN MODE)
|
142
|
-
|
143
|
-
GROUP BY comments.ID -- 26行目
|
144
|
-
ORDER BY comments.count_likes DESC, comments.ID DESC
|
145
|
-
LIMIT 0, 20
|
146
124
|
|
147
125
|
) UNION (
|
148
126
|
|
149
127
|
-- ➁「コメントについたタグ」をSELECT
|
150
|
-
SELECT
|
151
|
-
comments.ID AS comment_id
|
152
|
-
,comments.lang_id
|
153
|
-
,comments.comment
|
154
|
-
,comments.count_likes
|
155
|
-
,GROUP_CONCAT(
|
156
|
-
tags.ID
|
157
|
-
SEPARATOR '__SEPARATOR__'
|
158
|
-
) AS tag_ids
|
159
|
-
|
160
|
-
FROM
|
161
|
-
my_comments comments
|
162
|
-
LEFT JOIN my_tag_holders th
|
163
|
-
ON th.comments_ID = comments.ID
|
164
|
-
LEFT JOIN my_tags tags
|
165
|
-
ON tags.ID = th.tags_ID
|
166
|
-
|
167
|
-
|
128
|
+
-- 上と同じなので割愛
|
168
|
-
LEFT JOIN my_tag_holders th2
|
169
|
-
ON th2.comments_ID = comments.ID
|
170
|
-
LEFT JOIN my_tags tags2
|
171
|
-
ON tags2.ID = th2.tags_ID
|
172
|
-
|
173
|
-
-- '指導'を持つタグを指定
|
174
|
-
WHERE tags2.tag_name LIKE '%指導%'
|
175
|
-
|
176
|
-
GROUP BY comments.ID
|
177
|
-
ORDER BY comments.count_likes DESC, comments.ID DESC
|
178
|
-
LIMIT 0, 20
|
179
129
|
)
|
180
130
|
)x
|
181
131
|
|
1
➁を修正
test
CHANGED
File without changes
|
test
CHANGED
@@ -111,10 +111,10 @@
|
|
111
111
|
LIMIT 0, 20
|
112
112
|
```
|
113
113
|
|
114
|
-
### ➂
|
114
|
+
### ➂ ➀と➁をUNIONしてSELECT
|
115
|
-
疑問なのがこちらで、➀と
|
115
|
+
疑問なのがこちらで、➀と➁と同じ5つのカラムに対し、同じように66行目で「comment_idだけでまとめる」よう指定しているつもりなのですが、この場合にエラーになります。
|
116
|
-
```SQL
|
116
|
+
```SQL
|
117
|
-
-- ➂ ➀と
|
117
|
+
-- ➂ ➀と➁をUNIONしてSELECT
|
118
118
|
SELECT *
|
119
119
|
FROM (
|
120
120
|
(
|