質問編集履歴

4

CREATE TABLE部分を修正しました(不要なAUTO INCREMENTを含んでいたため)

2021/07/19 00:30

投稿

hika-rakuyo
hika-rakuyo

スコア15

test CHANGED
File without changes
test CHANGED
@@ -60,7 +60,7 @@
60
60
 
61
61
  PRIMARY KEY (`id`)
62
62
 
63
- ) ENGINE=InnoDB AUTO_INCREMENT=320 DEFAULT CHARSET=utf8;
63
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
64
64
 
65
65
 
66
66
 
@@ -88,7 +88,7 @@
88
88
 
89
89
  KEY `shops_project_id_index` (`project_id`)
90
90
 
91
- ) ENGINE=InnoDB AUTO_INCREMENT=320 DEFAULT CHARSET=utf8;
91
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
92
92
 
93
93
 
94
94
 
@@ -128,33 +128,177 @@
128
128
 
129
129
  KEY `earnings_shop_id_index` (`shop_id`)
130
130
 
131
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
132
+
133
+
134
+
135
+ INSERT INTO `earnings` VALUES
136
+
137
+ (1,999,1,'1','リンゴ味','2021-06-15','まあまあ売れた。',10,'2021-07-01 00:00:00','2021-07-01 00:00:00'),
138
+
139
+ (2,999,1,'2','ブドウ味','2021-06-20','少し売れた。',5,'2021-07-01 00:00:00','2021-07-01 00:00:00'),
140
+
141
+ (3,999,1,'1','リンゴ味','2021-06-30','かなり売れた。',20,'2021-07-01 00:00:00','2021-07-01 00:00:00');
142
+
143
+ ```
144
+
145
+ このうち、`earnings` テーブルには、ある店舗(`shop_id`)のある日(`earned_date`)におけるある商品(`item_id`)の総売上個数(`earning`)を、それひとつのみ入れていく形になります。
146
+
147
+ (テーブルの定義で`unique`系の制約もなく、分かりにくくて申し訳ありません…。)
148
+
149
+
150
+
151
+
152
+
153
+ なお、`item`に関するテーブルもあるのですが、必要な情報は`earnings`テーブルに織り込んでいて結合にも使用しないため、ここでは割愛します。
154
+
155
+
156
+
157
+ ### 実行内容
158
+
159
+ ```SQL
160
+
161
+ SELECT
162
+
163
+ `shops`.`id` AS `shop_id`,
164
+
165
+ `E1`.`id` AS `earning_id`,
166
+
167
+ `E1`.`earning` AS `max_earning`,
168
+
169
+ `E1`.`earned_date` AS `earned_date`,
170
+
171
+ `E1`.`comment` AS `comment`
172
+
173
+ FROM
174
+
175
+ `shops`
176
+
177
+ LEFT JOIN
178
+
179
+ `earnings` AS `E1`
180
+
181
+ ON
182
+
183
+ `E1`.`shop_id` = `shops`.`id`
184
+
185
+ AND
186
+
187
+ `E1`.`item_id` = 2 # ** POINT **
188
+
189
+ WHERE
190
+
191
+ `shops`.`project_id` = 999
192
+
193
+ AND
194
+
195
+ NOT EXISTS(
196
+
197
+ SELECT
198
+
199
+ 1
200
+
201
+ FROM
202
+
203
+ `earnings` AS `E2`
204
+
205
+ WHERE
206
+
207
+ E1.shop_id = E2.shop_id
208
+
209
+ AND
210
+
211
+ E1.earning < E2.earning
212
+
213
+ )
214
+
215
+ ;
216
+
217
+ ```
218
+
219
+
220
+
221
+
222
+
223
+ ### 発生している問題
224
+
225
+ 上記コードの`** POINT **`行にて、値を1にした場合と2にした場合で実行結果が変わってしまいます。
226
+
227
+ <`E1.item_id = 1`の場合>
228
+
229
+ ![実行結果1](5d455b9697483dc24dde1bbd2199288a.png)
230
+
231
+ <`E1.item_id = 2`の場合>
232
+
233
+ ![実行結果2](b525f13f15af4b2d44fe3aef0fcfe902.png)
234
+
235
+ `shop_id=1`でかつ`item_id=2`のレコードは一つ用意されているはずなのに、それがスキップされてしまいます。
236
+
237
+
238
+
239
+
240
+
241
+
242
+
243
+ ### 試したこと
244
+
245
+
246
+
247
+ **● `item_id` のデータ型が `varchar`になっている点に着目**
248
+
249
+
250
+
251
+ [1] データ型とINSERTを修正する → 実行結果変わらず
252
+
253
+ ```SQL
254
+
255
+ CREATE TABLE `earnings` (
256
+
257
+ `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
258
+
259
+ `project_id` int(11) NOT NULL,
260
+
261
+ `shop_id` int(11) NOT NULL,
262
+
263
+ `item_id` int(11) NOT NULL,
264
+
265
+ # `item_id` varchar(255) COLLATE utf8_unicode_ci NOT NULL, ** ここを上記に修正
266
+
267
+ `item_name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
268
+
269
+ `earned_date` date NOT NULL,
270
+
271
+ `comment` text COLLATE utf8_unicode_ci NOT NULL,
272
+
273
+ `earning` int(10) unsigned NOT NULL,
274
+
275
+ `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
276
+
277
+ `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
278
+
279
+ PRIMARY KEY (`id`),
280
+
281
+ KEY `earnings_project_id_index` (`project_id`),
282
+
283
+ KEY `earnings_shop_id_index` (`shop_id`)
284
+
131
285
  ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
132
286
 
133
287
 
134
288
 
135
289
  INSERT INTO `earnings` VALUES
136
290
 
137
- (1,999,1,'1','リンゴ味','2021-06-15','まあまあ売れた。',10,'2021-07-01 00:00:00','2021-07-01 00:00:00'),
291
+ (1,999,1,1,'リンゴ味','2021-06-15','まあまあ売れた。',10,'2021-07-01 00:00:00','2021-07-01 00:00:00'),
138
-
292
+
139
- (2,999,1,'2','ブドウ味','2021-06-20','少し売れた。',5,'2021-07-01 00:00:00','2021-07-01 00:00:00'),
293
+ (2,999,1,2,'ブドウ味','2021-06-20','少し売れた。',5,'2021-07-01 00:00:00','2021-07-01 00:00:00'),
140
-
294
+
141
- (3,999,1,'1','リンゴ味','2021-06-30','かなり売れた。',20,'2021-07-01 00:00:00','2021-07-01 00:00:00');
295
+ (3,999,1,1,'リンゴ味','2021-06-30','かなり売れた。',20,'2021-07-01 00:00:00','2021-07-01 00:00:00');
296
+
297
+ #********↑ ここの''を外す
142
298
 
143
299
  ```
144
300
 
145
- このうち、`earnings` テーブルには、ある店舗(`shop_id`)のある日(`earned_date`)におけるある商品(`item_id`)の総売上個数(`earning`)を、それひとつのみ入れていく形になります。
146
-
147
- (テーブルの定義で`unique`系の制約もなく、分かりくくて申し訳ありません…。)
301
+ [2] WHEREクエリを文字列検索向け修正する → 実行結果変わらず
148
-
149
-
150
-
151
-
152
-
153
- なお、`item`に関するテーブルもあるのですが、必要な情報は`earnings`テーブルに織り込んでいて結合にも使用しないため、ここでは割愛します。
154
-
155
-
156
-
157
- ### 実行内容
158
302
 
159
303
  ```SQL
160
304
 
@@ -184,12 +328,76 @@
184
328
 
185
329
  AND
186
330
 
331
+ `E1`.`item_id` LIKE '2' # ** ここを修正 **
332
+
333
+ WHERE
334
+
335
+ `shops`.`project_id` = 999
336
+
337
+ AND
338
+
339
+ NOT EXISTS(
340
+
341
+ SELECT
342
+
343
+ 1
344
+
345
+ FROM
346
+
347
+ `earnings` AS `E2`
348
+
349
+ WHERE
350
+
351
+ E1.shop_id = E2.shop_id
352
+
353
+ AND
354
+
355
+ E1.earning < E2.earning
356
+
357
+ )
358
+
359
+ ;
360
+
361
+ ```
362
+
363
+
364
+
365
+ **● いじった中での発見…**
366
+
367
+
368
+
369
+ [3] 15,16行目の `project_id`による絞込み制約を消すと、中身は`(null)`だが一応`shop_id=1`の列が立つ
370
+
371
+ ```SQL
372
+
373
+ SELECT
374
+
375
+ `shops`.`id` AS `shop_id`,
376
+
377
+ `E1`.`id` AS `earning_id`,
378
+
379
+ `E1`.`earning` AS `max_earning`,
380
+
381
+ `E1`.`earned_date` AS `earned_date`,
382
+
383
+ `E1`.`comment` AS `comment`
384
+
385
+ FROM
386
+
387
+ `shops`
388
+
389
+ LEFT JOIN
390
+
391
+ `earnings` AS `E1`
392
+
393
+ ON
394
+
395
+ `E1`.`shop_id` = `shops`.`id`
396
+
397
+ AND
398
+
187
399
  `E1`.`item_id` = 2 # ** POINT **
188
400
 
189
- WHERE
190
-
191
- `shops`.`project_id` = 999
192
-
193
401
  AND
194
402
 
195
403
  NOT EXISTS(
@@ -216,214 +424,6 @@
216
424
 
217
425
  ```
218
426
 
219
-
220
-
221
-
222
-
223
- ### 発生している問題
224
-
225
- 上記コードの`** POINT **`行にて、値を1にした場合と2にした場合で実行結果が変わってしまいます。
226
-
227
- <`E1.item_id = 1`の場合>
228
-
229
- ![実行結果1](5d455b9697483dc24dde1bbd2199288a.png)
230
-
231
- <`E1.item_id = 2`の場合>
232
-
233
- ![実行結果2](b525f13f15af4b2d44fe3aef0fcfe902.png)
234
-
235
- `shop_id=1`でかつ`item_id=2`のレコードは一つ用意されているはずなのに、それがスキップされてしまいます。
236
-
237
-
238
-
239
-
240
-
241
-
242
-
243
- ### 試したこと
244
-
245
-
246
-
247
- **● `item_id` のデータ型が `varchar`になっている点に着目**
248
-
249
-
250
-
251
- [1] データ型とINSERTを修正する → 実行結果変わらず
252
-
253
- ```SQL
254
-
255
- CREATE TABLE `earnings` (
256
-
257
- `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
258
-
259
- `project_id` int(11) NOT NULL,
260
-
261
- `shop_id` int(11) NOT NULL,
262
-
263
- `item_id` int(11) NOT NULL,
264
-
265
- # `item_id` varchar(255) COLLATE utf8_unicode_ci NOT NULL, ** ここを上記に修正
266
-
267
- `item_name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
268
-
269
- `earned_date` date NOT NULL,
270
-
271
- `comment` text COLLATE utf8_unicode_ci NOT NULL,
272
-
273
- `earning` int(10) unsigned NOT NULL,
274
-
275
- `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
276
-
277
- `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
278
-
279
- PRIMARY KEY (`id`),
280
-
281
- KEY `earnings_project_id_index` (`project_id`),
282
-
283
- KEY `earnings_shop_id_index` (`shop_id`)
284
-
285
- ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
286
-
287
-
288
-
289
- INSERT INTO `earnings` VALUES
290
-
291
- (1,999,1,1,'リンゴ味','2021-06-15','まあまあ売れた。',10,'2021-07-01 00:00:00','2021-07-01 00:00:00'),
292
-
293
- (2,999,1,2,'ブドウ味','2021-06-20','少し売れた。',5,'2021-07-01 00:00:00','2021-07-01 00:00:00'),
294
-
295
- (3,999,1,1,'リンゴ味','2021-06-30','かなり売れた。',20,'2021-07-01 00:00:00','2021-07-01 00:00:00');
296
-
297
- #********↑ ここの''を外す
298
-
299
- ```
300
-
301
- [2] WHEREクエリを文字列検索向けに修正する → 実行結果変わらず
302
-
303
- ```SQL
304
-
305
- SELECT
306
-
307
- `shops`.`id` AS `shop_id`,
308
-
309
- `E1`.`id` AS `earning_id`,
310
-
311
- `E1`.`earning` AS `max_earning`,
312
-
313
- `E1`.`earned_date` AS `earned_date`,
314
-
315
- `E1`.`comment` AS `comment`
316
-
317
- FROM
318
-
319
- `shops`
320
-
321
- LEFT JOIN
322
-
323
- `earnings` AS `E1`
324
-
325
- ON
326
-
327
- `E1`.`shop_id` = `shops`.`id`
328
-
329
- AND
330
-
331
- `E1`.`item_id` LIKE '2' # ** ここを修正 **
332
-
333
- WHERE
334
-
335
- `shops`.`project_id` = 999
336
-
337
- AND
338
-
339
- NOT EXISTS(
340
-
341
- SELECT
342
-
343
- 1
344
-
345
- FROM
346
-
347
- `earnings` AS `E2`
348
-
349
- WHERE
350
-
351
- E1.shop_id = E2.shop_id
352
-
353
- AND
354
-
355
- E1.earning < E2.earning
356
-
357
- )
358
-
359
- ;
360
-
361
- ```
362
-
363
-
364
-
365
- **● いじった中での発見…**
366
-
367
-
368
-
369
- [3] 15,16行目の `project_id`による絞込み制約を消すと、中身は`(null)`だが一応`shop_id=1`の列が立つ
370
-
371
- ```SQL
372
-
373
- SELECT
374
-
375
- `shops`.`id` AS `shop_id`,
376
-
377
- `E1`.`id` AS `earning_id`,
378
-
379
- `E1`.`earning` AS `max_earning`,
380
-
381
- `E1`.`earned_date` AS `earned_date`,
382
-
383
- `E1`.`comment` AS `comment`
384
-
385
- FROM
386
-
387
- `shops`
388
-
389
- LEFT JOIN
390
-
391
- `earnings` AS `E1`
392
-
393
- ON
394
-
395
- `E1`.`shop_id` = `shops`.`id`
396
-
397
- AND
398
-
399
- `E1`.`item_id` = 2 # ** POINT **
400
-
401
- AND
402
-
403
- NOT EXISTS(
404
-
405
- SELECT
406
-
407
- 1
408
-
409
- FROM
410
-
411
- `earnings` AS `E2`
412
-
413
- WHERE
414
-
415
- E1.shop_id = E2.shop_id
416
-
417
- AND
418
-
419
- E1.earning < E2.earning
420
-
421
- )
422
-
423
- ;
424
-
425
- ```
426
-
427
427
  → 実行結果
428
428
 
429
429
  ![実行結果3](445391eb7406cb5aeafea78f8d897590.png)

3

解消しました。他追記もしています。

2021/07/19 00:30

投稿

hika-rakuyo
hika-rakuyo

スコア15

test CHANGED
@@ -1 +1 @@
1
- データのMAX値を持つレコードをGROUP BY を使わずに絞込み、別のテーブルに結合させると、思うような結果が得られない
1
+ 【解決】データのMAX値を持つレコードをGROUP BY を使わずに絞込み、別のテーブルに結合させると、思うような結果が得られない
test CHANGED
@@ -142,9 +142,9 @@
142
142
 
143
143
  ```
144
144
 
145
- このうち、earningsテーブルには、ある店舗(shop_id)のある日(earned_date)におけるある商品(item_id)の総売上個数(earning)を、それひとつのみ入れていく形になります。
145
+ このうち、`earnings` テーブルには、ある店舗(`shop_id`)のある日(`earned_date`)におけるある商品(`item_id`)の総売上個数(`earning`)を、それひとつのみ入れていく形になります。
146
-
146
+
147
- (テーブルの定義でunique系の制約なく、説明がないと分かりにくいですよね…。)
147
+ (テーブルの定義で`unique`系の制約なく、分かりにくくて申し訳ありません…。)
148
148
 
149
149
 
150
150
 
@@ -432,6 +432,14 @@
432
432
 
433
433
 
434
434
 
435
- 必要であればLaravelのクエリビルダを掲載することも可能です。
435
+ ~~必要であればLaravelのクエリビルダを掲載することも可能です。
436
-
436
+
437
- ただし、このページとは別の質問としてお伺いする可能性もあります。予めご了承ください。
437
+ ただし、このページとは別の質問としてお伺いする可能性もあります。予めご了承ください。~~
438
+
439
+ ↑ この質問ページ内でご回答を頂く中で、Laravelでの問題も解消できると確信を持てました。本当にありがとうございました。
440
+
441
+
442
+
443
+ また、念のため申し上げますと、ここでは自分の手元にあるコードを別の例に書き換えて記載しております。
444
+
445
+ データの内容などは架空のものになりますので、安心してご検証いただければ幸いです。

2

2021/07/19 00:21

投稿

hika-rakuyo
hika-rakuyo

スコア15

test CHANGED
File without changes
test CHANGED
@@ -142,6 +142,14 @@
142
142
 
143
143
  ```
144
144
 
145
+ このうち、`earnings`テーブルには、ある店舗(`shop_id`)のある日(`earned_date`)におけるある商品(`item_id`)の総売上個数(`earning`)を、それひとつのみ入れていく形になります。
146
+
147
+ (テーブルの定義で`unique`系の制約がなく、説明がないと分かりにくいですよね…。)
148
+
149
+
150
+
151
+
152
+
145
153
  なお、`item`に関するテーブルもあるのですが、必要な情報は`earnings`テーブルに織り込んでいて結合にも使用しないため、ここでは割愛します。
146
154
 
147
155
 

1

体裁を整えました

2021/07/17 16:50

投稿

hika-rakuyo
hika-rakuyo

スコア15

test CHANGED
File without changes
test CHANGED
@@ -356,6 +356,8 @@
356
356
 
357
357
  **● いじった中での発見…**
358
358
 
359
+
360
+
359
361
  [3] 15,16行目の `project_id`による絞込み制約を消すと、中身は`(null)`だが一応`shop_id=1`の列が立つ
360
362
 
361
363
  ```SQL