【问题标题】:How to aggregate by values represented in multiple columns with postgresql如何使用 postgresql 按多列中表示的值进行聚合
【发布时间】:2021-03-05 18:23:07
【问题描述】:

我正在使用 postgresql 8.3.23
我有一个表,其中一个 ip 表示为 3 个不同的列。 在不使用多个连接和多个查询的情况下,按 IP 聚合并按列获取总和的最佳方法是什么?

表格

source trans dest
ip1 ip2
ip1 ip1 ip3
ip1 ip2 ip3
ip2 ip4 ip5

我想要得到什么

ip source trans dest
ip1 3 1 0
ip2 1 1 1
ip3 0 0 2
ip4 0 1 0
ip5 0 0 1

【问题讨论】:

  • 为什么你使用的 Postgres 版本已经超过 7 年了?
  • 简单来说,这是一个基于postgresql 8.3.23的Greenplum数据库。迁移到更体面的版本需要完全重建,这对于包含 3.8 PB 数据的数据库来说具有挑战性

标签: sql aggregate greenplum


【解决方案1】:

您可以取消透视并重新聚合:

select ip, sum(source), sum(trans), sum(dest)
from ((select source as ip, 1 as source, 0 as trans, 0 as dest
       from t
      ) union all
      (select trans as ip, 0 as source, 1 as trans, 0 as dest
       from t
      ) union all
      (select dest as ip, 0 as source, 0 as trans, 1 as dest
       from t
      )
     ) t
group by ip;

肯定有不同的方式来表达这种逻辑。但是谁还记得 Postgres 8.3 支持什么?

【讨论】:

  • 此查询包含拼写错误(第二个查询是“select trans”作为 ip 而不是“select source”等)但这绝对是我一直在寻找的技巧,谢谢。我将在下面发布完整的答案。
  • @ChrisChris。 . .谢谢你。固定。
【解决方案2】:

使用 Gordon 的技巧,我以以下查询结束。由于它用于汇总每天摄取的 55 亿个事件,其中一些 IP 过度表示,因此在子查询中获取总和结果证明效率更高。

select ip, sum(source_count) as source_count, sum(trans_count) as trans_count, sum(dest_count) as dest_count
from ((select source as ip, count(*) as source_count, 0 as trans_count, 0 as dest_count
       from t where source is not null
       group by 1,3,4
      ) union all
      (select trans as ip, 0 as source_count, count(*) as trans_count, 0 as dest_count
       from t where trans is not null
       group by 1,2,4
      ) union all
      (select dest as ip, 0 as source_count, 0 as trans_count, count(*) as dest_count
       from t where dest is not null
       group by 1,2,3
      )
     ) t
group by ip
order by ip;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-27
    • 2016-11-19
    • 1970-01-01
    • 1970-01-01
    • 2023-02-23
    相关资源
    最近更新 更多