【发布时间】:2020-05-09 21:58:31
【问题描述】:
我有一个包含两列的行集:technical_id 和 natural_id。行集实际上是复杂查询的结果。假定列值之间的映射是双射的(即,对于具有相同 technical_id 的两行,natural_ids 也相同,对于不同的 technical_ids,natural_ids 也是不同的)。由于原始查询中的连接,(technical_id,natural_id) 对在行集中不是唯一的。示例:
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)
)
不幸的是,双射仅由应用程序逻辑强制执行。 natural_id 实际上是从多个表中收集的,并使用基于coalesce 的表达式组合而成,因此它的唯一性几乎无法通过 db 约束来强制执行。
假设natural_id 是唯一的,我需要通过technical_id 聚合行集的行。如果不是(例如,如果将元组 (4, 'x', 1) 添加到示例数据中),则查询应该失败。在理想的 SQL 世界中,我会使用一些假设的聚合函数:
select technical_id, only(natural_id), sum(val)
from t
group by technical_id;
我知道 SQL 中没有这样的功能。是否有一些替代方案或解决方法? Postgres 特有的解决方案也可以。
请注意,group by technical_id, natural_id 或 select technical_id, max(natural_id) - 尽管在愉快的情况下工作得很好 - 都是不可接受的(首先因为 technical_id 在所有情况下的结果中都必须是唯一的,其次因为该值可能是随机的并且掩盖了数据不一致)。
感谢您的提示:-)
更新:预期的答案是
technical_id,v,sum
1,a,3
2,b,5
3,c,1
4,d,1
当4,x,1 也存在时失败。
【问题讨论】:
-
您能否通过显示示例数据的预期结果来扩展问题?
-
我不太愿意回答 - 但感觉您可能正在寻找 HAVING COUNT() 子句
标签: sql postgresql aggregate unique aggregate-functions