Имя столбца, похоже, используется вместо псевдонима в GROUP BY

#postgresql

#postgresql

Вопрос:

Для проекта я хочу получить все результаты по группам за день.

Вот мой запрос:

 SELECT MAX(id) AS id, 
       SUM(value) AS value, 
       country, 
       cast(TO_CHAR(date, 'dd/mm/yyyy') AS DATE) AS date 
FROM records 
GROUP BY date, country
  

Моя проблема в том, что записи неправильно группируются, когда я использую свой псевдоним «дата», вместо этого он, похоже, группируется по имени поля.

Результаты с group by alias

Результаты с group by alias

Это работает, если я использую индексы вместо псевдонима, но я бы хотел, чтобы в моем результате было имя столбца :

 SELECT MAX(id) AS id, 
       SUM(value) AS value, 
       country, 
       cast(TO_CHAR(date, 'dd/mm/yyyy') AS DATE) AS date 
FROM records 
GROUP BY 3, 4
  

Результаты с group by indexes

Результаты с group by indexes

Есть ли у кого-нибудь идея, почему это работает таким образом?

Комментарии:

1. Не связано, но: если date это timestamp , вы также можете использовать date::date для удаления временной части метки времени

2. Что не так со второй версией, которая, похоже, решает вашу проблему?

3. Да, это работает, но я хотел бы понять, почему это не работает в первой версии!

Ответ №1:

Цитата из руководства

Выражение, используемое внутри grouping_element, может быть именем входного столбца, или именем или порядковым номером выходного столбца (элемент списка ВЫБОРА), или произвольным выражением, сформированным из значений входного столбца. В случае неоднозначности, ГРУППА ПО имени будет интерпретироваться как имя входного столбца, а не имя выходного столбца

(выделение мое)

Таким образом, (входные) имена столбцов всегда имеют приоритет над псевдонимами столбцов.

Ответ №2:

Эти два GROUP BY предложения не эквивалентны.

В обоих SELECT предложении:

 SELECT
    MAX(id) AS id, 
    SUM(value) AS value, 
    country, 
    cast(TO_CHAR(date, 'dd/mm/yyyy') AS DATE) AS date
  

Таким образом, столбцы будут ( id , value , country , date , ,,).

Первый запрос группируется по, date затем country :

 GROUP BY date, country
  

Вторые группы к country тому date времени:

 GROUP BY 3, 4
  

С другой иерархией GROUP BY вы получите разные результаты, например, то, что вы показываете.