Я часто добавляю выражения в предложение group by
, которые, я уверен, уникальны.Иногда оказывается, что я ошибаюсь - из-за ошибки в моем SQL или ошибочного предположения, и что это выражение на самом деле не уникально.
Есть много случаев, когда я бы предпочел, чтобы это вызвало скорее ошибку SQLчем молча, иногда очень тонко, расширять свой набор результатов.
Я бы хотел сделать что-то вроде:
select product_id, unique description from product group by product_id
, но, очевидно, я не могу реализовать это сам - но что-то почтикраткий отчет может быть реализован с помощью пользовательских агрегатов в некоторых базах данных.
Может ли специальный агрегат, который допускает только одно уникальное входное значение, быть полезным во всех версиях SQL?Если да, может ли такая вещь быть реализована сейчас в большинстве баз данных?Значения null
следует рассматривать так же, как и любое другое значение, в отличие от того, как обычно работает встроенный агрегат avg
.(Я добавил ответы о способах реализации этого для postgres и Oracle.)
В следующем примере показано, как будет использоваться агрегат, но это простой случай, когда очевидно, какие выражения должны быть уникальными.,Скорее всего, реальное использование будет в больших запросах, где легче сделать ошибочные предположения об уникальности
таблиц:
product_id | description
------------+-------------
1 | anvil
2 | brick
3 | clay
4 | door
sale_id | product_id | cost
---------+------------+---------
1 | 1 | £100.00
2 | 1 | £101.00
3 | 1 | £102.00
4 | 2 | £3.00
5 | 2 | £3.00
6 | 2 | £3.00
7 | 3 | £24.00
8 | 3 | £25.00
запросов:
> select * from product join sale using (product_id);
product_id | description | sale_id | cost
------------+-------------+---------+---------
1 | anvil | 1 | £100.00
1 | anvil | 2 | £101.00
1 | anvil | 3 | £102.00
2 | brick | 4 | £3.00
2 | brick | 5 | £3.00
2 | brick | 6 | £3.00
3 | clay | 7 | £24.00
3 | clay | 8 | £25.00
> select product_id, description, sum(cost)
from product join sale using (product_id)
group by product_id, description;
product_id | description | sum
------------+-------------+---------
2 | brick | £9.00
1 | anvil | £303.00
3 | clay | £49.00
> select product_id, solo(description), sum(cost)
from product join sale using (product_id)
group by product_id;
product_id | solo | sum
------------+-------+---------
1 | anvil | £303.00
3 | clay | £49.00
2 | brick | £9.00
случай ошибки:
> select solo(description) from product;
ERROR: This aggregate only allows one unique input