如何在有重复记录的Postgres数据库中汇总不同的记录?

Kat*_*e F 8 postgresql

想象一下这样的表:

具有重复数据的表

获取此数据的SQL只是SELECT*第一列是"row_id",第二列是"id" - 这是订单ID,第三列是"total" - 这是收入.

我不确定为什么数据库中有重复的行,但是当我执行SUM(总计)时,它包括数据库中的第二个条目,即使订单ID相同,这导致我的数字更大比如果我选择distinct(id),total - export to excel然后手动求和.

所以我的问题是 - 如何只对不同的订单ID进行汇总,以便获得相同的收入,就好像我导出到excel每个不同的订单ID行?

提前致谢!

Boh*_*ian 12

容易 - 除以计数:

select id, sum(total) / count(id)
from orders
group by id
Run Code Online (Sandbox Code Playgroud)

还处理任何级别的重复,例如一式三份等.

  • 这太聪明了! (2认同)
  • 这不会根据需要返回所有不同记录的“总计”总和。 (2认同)
  • 这看起来像是一个过度拟合的解决方案——我们也可以只返回文字并证明它适用于 OP 的数据。 (2认同)

zed*_*xus 7

你可以尝试这样的事情(用你的例子):

桌子

create table test (
  row_id int,
  id int,
  total decimal(15,2)
);

insert into test values 
(6395, 1509, 112), (22986, 1509, 112), 
(1393, 3284, 40.37), (24360, 3284, 40.37);
Run Code Online (Sandbox Code Playgroud)

询问

with distinct_records as (
  select distinct id, total from test
)

select a.id, b.actual_total, array_agg(a.row_id) as row_ids
from test a
inner join (select id, sum(total) as actual_total from distinct_records group by id) b
  on a.id = b.id
group by a.id, b.actual_total
Run Code Online (Sandbox Code Playgroud)

结果

|   id | actual_total |    row_ids |
|------|--------------|------------|
| 1509 |          112 | 6395,22986 |
| 3284 |        40.37 | 1393,24360 |
Run Code Online (Sandbox Code Playgroud)

解释

我们不知道订单和总计以不同的 row_id 出现多次的原因是什么。因此,使用使用该with ...短语的公共表表达式 (CTE),我们可以获得不同的 id 和总计。

在 CTE 下,我们使用这些不同的数据进行总计。我们将原始表中的 ID 与不同值的聚合连接起来。然后我们用逗号分隔 row_ids,以便信息看起来更清晰。

SQLFiddle 示例

http://sqlfiddle.com/#!15/72639/3


小智 5

创建自定义聚合:

CREATE OR REPLACE FUNCTION sum_func (
  double precision, pg_catalog.anyelement, double precision
)
RETURNS double precision AS
$body$
SELECT case when $3 is not null then COALESCE($1, 0) + $3 else $1 end
$body$
LANGUAGE 'sql';

CREATE AGGREGATE dist_sum (
  pg_catalog."any", 
  double precision)
(
  SFUNC = sum_func,
  STYPE = float8
);
Run Code Online (Sandbox Code Playgroud)

然后计算不同的总和,例如:

select dist_sum(distinct id, total)
from orders
Run Code Online (Sandbox Code Playgroud)

SQLFiddle