Разве PostgreSQL автоматически обнаруживает уникальные записи в выражении group by? - PullRequest
0 голосов
/ 24 марта 2019

Не обязательно ли в PostgreSQL добавлять уникальный столбец в группу по предложению?

Я обычно использую Microsoft SQL Server, в котором мы должны добавить все необходимые столбцы в группу по предложению.

Запрос PostgreSQL:

DROP TABLE IF EXISTS temp_invoice_detail;
CREATE TEMP TABLE temp_invoice_detail(
    invoice_id integer,
    item_id integer,
    qty integer,
    warehouse_id integer    
);

ALTER TABLE temp_invoice_detail ADD CONSTRAINT temp_invoice_detail_result_pkey PRIMARY KEY (invoice_id, item_id);

insert into temp_invoice_detail (invoice_id, item_id, qty, warehouse_id) values (1, 1, 100, 1);
insert into temp_invoice_detail (invoice_id, item_id, qty, warehouse_id) values (1, 2, 200, 1);
insert into temp_invoice_detail (invoice_id, item_id, qty, warehouse_id) values (2, 1, 100, 1);

select invoice_id, item_id, sum(qty) as total_qty, warehouse_id
from temp_invoice_detail
group by invoice_id, item_id --should I add "warehouse_id" in group by clause?
order by invoice_id, item_id;

DROP TABLE IF EXISTS temp_invoice_detail;

Я ожидаю, что сообщение об ошибке отображения PostgreSQL:

столбец «temp_invoice_detail.warehouse_id» должен появиться в предложении GROUP BY или использоваться в статистической функции

Но запрос выполняется успешно и возвращает 3 записи (все 3 записи в инструкции вставки выше).

invoice_id  item_id  total_qty  warehouse_id
1           1        100        1
1           2        200        1
2           1        100        1

В MS-SQL этот запрос может выполняться без ошибок, группапо предложению должно быть:

сгруппировать по invoice_id, item_id, warehouse_id

1 Ответ

4 голосов
/ 24 марта 2019

Это потому, что вы определили invoice_id, item_id как первичный ключ таблицы, и достаточно группировки по уникальному ключу, так как добавление большего числа столбцов в группу не изменит результат группы на.

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

Когда присутствует GROUP BY или присутствуют какие-либо агрегатные функции, недопустимо, чтобы выражения списка SELECT ссылались наразгруппированные столбцы, кроме как в агрегатных функциях или когда несгруппированный столбец функционально зависит от сгруппированных столбцов , поскольку в противном случае было бы более одного возможного значения, которое можно вернуть для разгруппированного столбца.Функциональная зависимость существует, если сгруппированные столбцы (или их подмножество) являются первичным ключом таблицы, содержащей несгруппированный столбец

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

Это фактически разрешено стандартом SQL.Postgres даже доходит до того, что удаляет ненужные столбцы (в зависимости от наличия первичных или уникальных ключей) из группы, поскольку это повышает производительность.

...