【问题标题】:Comparing rows vs array elements postgres比较行与数组元素postgres
【发布时间】:2018-06-23 11:54:57
【问题描述】:

我有一个表 An 行 (200+) 和不同的数字列。
我有一个表Bm 行(100K+)和一个名为multipliers 的列,它是数组类型(REAL[])。对于B 中的每一行,这个数组的长度是n,即。 A 中每个数值变量的乘数。对数组进行排序以匹配Aid 字段的字母顺序

A

id | values_1 | values_2
---|----------|-------------
1  | 11.2     | 10.2
2  | 21.9     | 12.5
3  | 30.0     | 26.0
4  | 98.0     | 11.8

B

id      | multipliers
--------|-------------
dafcec  | {2,3,4,9}
nkjhbn  | {0,0,1,5}
ccseff  | {1,2,0,5}
ddeecc  | {0,0,0,1}

我需要一个返回 SUM( multipliers * values_1 ) 的查询。

像这样:

b.id    | sum(b.multipliers*a.value_1)
--------|----------------------------------
dafcec  | 2*11.2 + 3*21.9 + 4*30.0 + 9*98.0
nkjhbn  | 0*11.2 + 0*21.9 + 1*30.0 + 5*98.0
ccseff  | 1*11.2 + 2*21.9 + 0*30.0 + 5*98.0
ddeecc  | 0*11.2 + 0*21.9 + 0*30.0 + 1*98.0

我尝试了不同的子查询,LATERAL joins 和 UNNEST,但我无法获得有效的结果。
有什么提示吗?谢谢!

【问题讨论】:

    标签: sql arrays postgresql lateral-join


    【解决方案1】:

    最简单但我相信对数组求和的方法是:

    t=# with b as (select id,unnest(multipliers) u from b)
    select distinct id, sum(u)over (partition by id) from b;
        id    | sum
    ----------+-----
     ccseff   |   8
     nkjhbn   |   6
     ddeecc   |   1
     dafcec   |  18
    (4 rows)
    

    我没有想到任何快速的替代方案......

    进一步 - 如果我猜对了,你想要一个笛卡尔积 - 全部反对,那么:

    t=# with b as (select id,unnest(multipliers) u from b)
    , ag as (select distinct id, sum(u)over (partition by id) from b)
    select ag.sum * v1, a.id aid, ag.id idb
    from ag
    join a on true;
     ?column? | aid |   idb
    ----------+-----+----------
         89.6 |   1 | ccseff
        175.2 |   2 | ccseff
          240 |   3 | ccseff
          784 |   4 | ccseff
         67.2 |   1 | nkjhbn
        131.4 |   2 | nkjhbn
          180 |   3 | nkjhbn
          588 |   4 | nkjhbn
         11.2 |   1 | ddeecc
         21.9 |   2 | ddeecc
           30 |   3 | ddeecc
           98 |   4 | ddeecc
        201.6 |   1 | dafcec
        394.2 |   2 | dafcec
          540 |   3 | dafcec
         1764 |   4 | dafcec
    (16 rows)
    

    【讨论】:

    • 感谢您的帮助!我编辑了问题以概述我希望实现的解决方案。最后,我需要每行一个b.id 和一个sum(b.multipliers * a.values_1) 的结果。我希望编辑有助于澄清它!
    • 如果它回答了您的问题,请接受和/或投票
    【解决方案2】:

    解决了。
    它只需要将values 打包成一个数组并解压缩它们,以便它们具有可比性。它对我有用。 ORDER BY 确保按所需顺序进行包装。

       SELECT id, SUM (field * multiplier) result FROM 
        (
        with c as (
            SELECT array_agg( values_1 ORDER BY name ASC) val1
            from A
        ) 
    
        , ag as (
            select
                distinct id,
                multipliers
            from B
            )
    
        SELECT
            ag.id, 
            unnest(c.val1) field,
            unnest(ag.multipliers) multiplier
        FROM
            c, ag
        ) s
    GROUP BY id
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-24
      • 1970-01-01
      • 1970-01-01
      • 2018-06-28
      • 2019-11-12
      • 2017-01-12
      • 2013-09-07
      • 1970-01-01
      相关资源
      最近更新 更多