如何在 PostgreSQL 中过滤和求和整数数组

Posted

技术标签:

【中文标题】如何在 PostgreSQL 中过滤和求和整数数组【英文标题】:How to filter and sum the array of integers in PostgreSQL 【发布时间】:2021-09-10 21:51:32 【问题描述】:

我有一项任务需要将id_user 执行的所有topup_val 相加,其中至少有一个topup_val 精确到15 欧元。此任务需要在单个SELECT 语句中解决,没有任何窗口函数或子查询(嵌套SELECT)。我仍然是 SQL 的初学者,所以我发现完成这项任务很困难。

我使用array_agg() 将每个id_usertopup_val 行转换为数组。但是,我无法使用WHERE 子句过滤数组,因为WHERE 子句在聚合函数之前执行。

非常感谢!

topups

 id_user | topup_val
---------+-----------
    1    |    10
    1    |    15
    1    |    5
    2    |    10
    2    |    10
    3    |    15
    3    |    15
    3    |    10

转换为数组

 id_user | topup_array
---------+------------------
    1    |     10, 15, 5
    2    |        10, 10
    3    |    15, 15, 10

预期结果

 id_user | topup_sum
---------+------------
    1    |     30
    3    |     40

我的 PostgreSQL 查询

SELECT id_user, array_agg(topup_val) AS array_topup
    FROM topups 
    WHERE 15 = ANY(array_topup)
    GROUP BY id_user
    ORDER BY id_user;

【问题讨论】:

您可以使用HAVING 子句过滤聚合。添加一个像HAVING 15 = array_agg(topup_val) (别名不能在HAVING 子句中引用)。您也可以在SELECT 中简单地使用SUM(topup_val) 【参考方案1】:

使用HAVING 而不是WHERE。 i出现在GROUP BY子句之后,是聚合后计算出来的,所以可以用来过滤聚合后的行。

【讨论】:

【参考方案2】:

在 group by 和 order by 之间,您可以使用 HAVING 进一步过滤您的结果集:

SELECT id_user,sum(topup_val)
FROM topups 
GROUP BY id_user
HAVING array_agg(topup_val) && array[15]
ORDER BY id_user;

演示:db<>fiddle

WITH topups (id_user,topup_val) AS ( VALUES
(1,10),(1,15),(1,5),(2,10),(2,10),(3,15),(3,15),(3,10)) 
SELECT id_user, sum(topup_val)
FROM topups 
GROUP BY id_user
HAVING array_agg(topup_val) && array[15]
ORDER BY id_user;

 id_user | sum 
---------+-----
       1 |  30
       3 |  40
(2 rows)

【讨论】:

太好了!我不知道我可以使用 HAVING 子句中的聚合函数,还可以使用 array[15] 在数组中搜索 15 值。非常感谢!

以上是关于如何在 PostgreSQL 中过滤和求和整数数组的主要内容,如果未能解决你的问题,请参考以下文章

在 Swift 中过滤对象数组并求和它们的属性

如何对整数字符串数组求和?

PostgreSQL 和 JDBC 使用 setArray 设置整数数组抛出异常“无法将类型整数 [] 转换为整数”

对多维数组javascript中的所有整数求和

如何在jquery中过滤数组后获取对象

给定的数组任意取出三个数(要求全部取到且不能重复)求和,找出和中最小值 Java 说说思路或者算法就