I have an rowset with two columns: technical_id
and natural_id
. The rowset is actually result of complex query. The mapping between columns values is assumed to be bijective (i.e. for two rows with same technical_id
the natural_id
s are same too, for distinct technical_id
s the natural_id
s are distinct too). The (technical_id,natural_id)
pairs are not unique in rowset because of joins in original query. Example:
with t (technical_id, natural_id, val) as (values
(1, 'a', 1),
(1, 'a', 2),
(2, 'b', 3),
(2, 'b', 2),
(3, 'c', 0),
(3, 'c', 1),
(4, 'd', 1)
)
Unfortunately, the bijection is enforced only by application logic. The natural_id
is actually collected from multiple tables and composed using coalesce
-based expression so its uniqueness hardly can be enforced by db constraint.
I need to aggregate rows of rowset by technical_id
assuming the natural_id
is unique. If it isn't (for example if tuple (4, 'x', 1)
were added into sample data), the query should fail. In ideal SQL world I would use some hypothetical aggregate function:
select technical_id, only(natural_id), sum(val)
from t
group by technical_id;
I know there is not such function in SQL. Is there some alternative or workaround? Postgres-specific solutions are also ok.
Note that group by technical_id, natural_id
or select technical_id, max(natural_id)
- though working well in happy case - are both unacceptable (first because the technical_id
must be unique in result under all circumstances, second because the value is potentially random and masks data inconsistency).
Thanks for tips :-)
UPDATE: the expected answer is
technical_id,v,sum
1,a,3
2,b,5
3,c,1
4,d,1
or fail when 4,x,1
is also present.