Проблема с group by

Здравствуйте.
Передо мной встала вполне стандартная задача выбора максимального значения за каждый месяц.

Вот такой код я написал:

SELECT
   MAX(statement_value) AS max_statement_value, 
   EXTRACT (month FROM statement_date) AS month
FROM acc_counters_statements_flats
WHERE
   counter_id = 36
GROUP BY month
ORDER BY month

Вот такую выдачу я получаю:

max_statement_value month
220
8
225
9

Всё отлично выбирает, но мне захотелось получить в выдаче не только два поля но и все остальные от этой таблицы. Поставив в select *, постгре стал ругаться на то что все поля должны быть перечислены в group by.
В итоге получился у меня такой запрос:

SELECT
   *,
   MAX(statement_value) AS max_statement_value, 
   EXTRACT (month FROM statement_date) AS month
FROM acc_counters_statements_flats
WHERE
   counter_id = 36
GROUP BY month, statement_id, statement_value, statement_date, counter_id, flat_id, house_id
ORDER BY month

Но в таком виде из-за группировки я получаю не ту выдачу (я получаю больше строк чем надо).

statement_id counter_id statement_value statement_date flat_id house_id max_statement_value month
164
36
220
2011-08-30 13:13:51+04
36
NULL
220
8
169
36
221
2011-09-21 13:14:24+04
36
NULL
221
9
174
36
222
2011-09-25 13:14:33+04
36
NULL
222
9
179
36
225
2011-09-26 13:14:45+04
36
NULL
225
9

Как бы мне получить выдачу как в первом запросе но со всеми полями таблицы?

Опции просмотра комментариев

Выберите предпочитаемый вами способ показа комментариев и нажмите "Сохранить настройки" для активации изменений.

Очевидно, что никак. GROUP BY

Очевидно, что никак. GROUP BY как бы сворачивает строки результата по одинаковым значениям. А у вас они неодинаковы, вот и получается то, что получается. Сами подумайте, какие значения вам должно показать в случае выдачи 2-х строк для month 9, если у трёх строк они разные?

Оттолкнувшись от этого я

Оттолкнувшись от этого я решил избавиться от неодинаковых полей в group by. "Неуникальным и всёпортящим" оказалась дата. Поэтому её засунул в аггрегатор max, чтобы не указывать её в списке группировки.
В итоге получился у меня такой запрос, который выдаёт мне всё что нужно:

SELECT
   MAX(statement_value) AS max_statement_value,
   MAX(statement_date) AS max_date,
   EXTRACT (month FROM statement_date) AS month,
   counter_id, flat_id
FROM acc_counters_statements_flats
WHERE
   flat_id = 36
GROUP BY month, counter_id, flat_id
ORDER BY month

Ну вот видите как хорошо.

Ну вот видите как хорошо. Стоило разобраться "как это работает" и решение нашлось

Опции просмотра комментариев

Выберите предпочитаемый вами способ показа комментариев и нажмите "Сохранить настройки" для активации изменений.

Back to top

(С) Виктор Вислобоков, 2008-2023