【问题标题】:How to filter and sum the array of integers in PostgreSQL如何在 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)

标签: sql arrays postgresql aggregate-functions


【解决方案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 值。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2021-07-14
    • 2011-01-26
    • 2021-01-14
    • 1970-01-01
    • 1970-01-01
    • 2019-01-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多