Tom*_*ský 5 sql postgresql aggregate unique aggregate-functions
我有一个包含两列的行集: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)
)
Run Code Online (Sandbox Code Playgroud)
不幸的是,双射仅由应用程序逻辑强制执行。的natural_id实际上是从多个表收集并使用由coalesce基于表达式,以便它的独特性几乎可以通过分贝约束来执行。
我需要通过technical_id假设natural_id是唯一的来聚合行集的行。如果不是(例如,如果将元组(4, 'x', 1)添加到示例数据中),则查询应该失败。在理想的 SQL 世界中,我会使用一些假设的聚合函数:
select technical_id, only(natural_id), sum(val)
from t
group by technical_id;
Run Code Online (Sandbox Code Playgroud)
我知道 SQL 中没有这样的功能。有什么替代方法或解决方法吗?Postgres 特定的解决方案也可以。
请注意,group by technical_id, natural_idor select technical_id, max(natural_id)- 尽管在愉快的情况下运行良好 - 都是不可接受的(首先是因为technical_id在所有情况下结果都必须是唯一的,其次是因为该值可能是随机的并掩盖了数据的不一致)。
感谢您的提示:-)
更新:预期的答案是
technical_id,v,sum
1,a,3
2,b,5
3,c,1
4,d,1
Run Code Online (Sandbox Code Playgroud)
或失败时4,x,1也存在。
似乎我终于找到了基于 select 子句中相关子查询的单行基数的解决方案:
select technical_id,
(select v from unnest(array_agg(distinct natural_id)) as u(v)) as natural_id,
sum(val)
from t
group by technical_id;
Run Code Online (Sandbox Code Playgroud)
对于我目前的情况来说,这是最简单的解决方案,所以我将诉诸自我接受。无论如何,如果出现一些缺点,我会在这里描述它们并重新接受其他答案。我感谢所有其他建议,并相信它们对任何人都有价值。
| 归档时间: |
|
| 查看次数: |
764 次 |
| 最近记录: |