Допустим, вы имеете следующую таблицу:
+----+-----+-----------+
| f1 | f2 | f3 |
+----+-----+-----------+
| 1 | 4.3 | apple |
| 2 | 1.4 | orange |
| 2 | 3 | pear |
| 3 | 1.2 | kiwi |
| 3 | 2.2 | pineapple |
| 3 | 1 | pineapple |
+----+-----+-----------+
И вы исполняете:
SELECT f1, sum(f2), f3 FROM table GROUP BY f1, f3;
Мы включают f1
и f3
столбцы в GROUP BY, чтобы сообщить MySQL, как агрегировать. Вы получите обратно:
+----+-----+-----------+
| f1 | f2 | f3 |
+----+-----+-----------+
| 1 | 4.3 | apple |
| 2 | 1.4 | orange |
| 2 | 3 | pear |
| 3 | 1.2 | kiwi |
| 3 | 3.3 | pineapple |
+----+-----+-----------+
Здесь мы получаем различные группировки f1
и f3
записей, как мы ожидаем.
Если вы опускаете либо f1
, либо f3
в GROUP BY, каждая РСУБД на планете собирается выбросить ошибку, кроме MySQL. Базы данных, отличные от MySQL, требуют, чтобы вы четко указывали, как вы суммируете свои поля, и они либо должны быть сгруппированы в GROUP BY
, либо объединены с формулой в SELECT
.
Если в MySQL, вы опускаете GROUP BY
:
SELECT f1, sum(f2), f3 FROM table;
вы получите записи назад, как:
+----+-----+-----------+
| f1 | f2 | f3 |
+----+-----+-----------+
| 1 | 4.3 | apple |
| 2 | 4.4 | orange |
| 3 | 4.5 | kiwi |
+----+-----+-----------+
, которые могут быть нонсенсом. Референциальная целостность ваших записей была скомпрометирована. Oranges
не 4.4
и Kiwi
не 4.5
. То, что сделал MySQL, - это первое значение, которое оно встретило в таблице, и выплюнуть его. Такое поведение может иметь смысл, если:
- Вы не заботятся о том, какое значение MySQL выбирает из
f3
или ...
- Вы полагаетесь на двигатель хранения MySQL, чтобы поддерживать порядок ваших записей, что, следовательно, делает вас дураком. Не делай этого.
Ваш лучший выбор для переносимости кода и неожиданных результатов будет включать GROUP BY
если вы агрегирование с функцией в вашем SELECT
. В противном случае вы получите то, что заслуживаете.
Общее правило GROUP BY: «Если указано предложение GROUP BY, каждая ссылка столбца в списке SELECT должна либо идентифицировать столбец группировки, либо быть аргументом функции набора.«Если вы нарушите это правило, то более старые версии MySQL сделают что-то по-другому, несколько непредсказуемым образом. Новейшие версии MySQL, тем не менее, вызовут ошибку. – jarlh
На самом деле это очень сложно ответить на все поддельные имена столбцов и не знать, что вы пытаетесь выполнить с вашим запросом – user2278120
@jarlh А, так что с моими данными он может «генерировать» результаты, пока каждая запись содержит столбец группы? – user1032531