PostgreSQL聚合函数,用于跨越多个未知数量的列的每一行

时间:2017-04-06 19:00:39

标签: postgresql aggregate-functions postgresql-9.3

我查看了类似this one之类的问题,但它们似乎有一个确定数量的列。我想输入一个我不知道列数的表。

问题:

如果事先确定列数 ,如何计算多列中每行的汇总函数(例如avg()sum())?

我已将输入表panel_stats_rnd csv和DLL创建为here

我想计算每一行rnd_avg_parcelcount作为所有列c_1_avg_parcelcountc_2_avg_parcelcount,...的平均值,其中我可以有任意数字的输入表(比如说100) _avg_parcelcount的列。对于列rnd_sum_parcelcount,我想计算以sum()开头并以c_结尾的所有列的_sum_parcelcount

表格如下:

SELECT * FROM panel_stats_rnd;
 gid | d  | dist_from | dist_to | distlabel | rnd_avg_parcelcount | rnd_sum_parcelcount | rnd_avg_callcount | rnd_sum_callcount | rnd_avg_perccalled | called_avg_parcelcount | called_sum_parcelcount | called_avg_callcount | called_sum_callcount | called_avg_perccalled | c_1_avg_parcelcount | c_1_sum_parcelcount | c_1_avg_callcount | c_1_sum_callcount |  c_1_avg_perccalled  | c_2_avg_parcelcount | c_2_sum_parcelcount | c_2_avg_callcount | c_2_sum_callcount |  c_2_avg_perccalled  
-----+----+-----------+---------+-----------+---------------------+---------------------+-------------------+-------------------+--------------------+------------------------+------------------------+----------------------+----------------------+-----------------------+---------------------+---------------------+-------------------+-------------------+----------------------+---------------------+---------------------+-------------------+-------------------+----------------------
   1 |  0 |         0 |     100 | 0-100     |                     |                     |                   |                   |                    |                 119045 |                 119045 |               119045 |                   23 |  0.000193204250493511 |              119045 |              119045 |            119045 |                16 | 0.000134402956865051 |              119045 |              119045 |            119045 |                16 | 0.000134402956865051
   2 |  1 |       100 |     200 | 100-200   |                     |                     |                   |                   |                    |                 163140 |                 163140 |               163140 |                   22 |  0.000134853500061297 |              163140 |              163140 |            163140 |                17 | 0.000104204977320093 |              163140 |              163140 |            163140 |                18 | 0.000110334681868334
   3 |  2 |       200 |     300 | 200-300   |                     |                     |                   |                   |                    |                 135934 |                 135934 |               135934 |                   10 |   7.3565112481057e-05 |              135934 |              135934 |            135934 |                18 | 0.000132417202465903 |              135934 |              135934 |            135934 |                15 | 0.000110347668721585
   4 |  3 |       300 |     400 | 300-400   |                     |                     |                   |                   |                    |                 116874 |                 116874 |               116874 |                   13 |  0.000111230898232284 |              116874 |              116874 |            116874 |                11 | 9.41184523503944e-05 |              116874 |              116874 |            116874 |                18 | 0.000154012012937009
   5 |  4 |       400 |     500 | 400-500   |                     |                     |                   |                   |                    |                  93216 |                  93216 |                93216 |                   12 |  0.000128733264675592 |               93216 |               93216 |             93216 |                10 | 0.000107277720562993 |               93216 |               93216 |             93216 |                12 | 0.000128733264675592
   6 |  5 |       500 |     600 | 500-600   |                     |                     |                   |                   |                    |                  69992 |                  69992 |                69992 |                    7 |    0.0001000114298777 |               69992 |               69992 |             69992 |                10 | 0.000142873471253858 |               69992 |               69992 |             69992 |                 7 |   0.0001000114298777
   7 |  6 |       600 |     700 | 600-700   |                     |                     |                   |                   |                    |                  50816 |                  50816 |                50816 |                   10 |  0.000196788413098237 |               50816 |               50816 |             50816 |                 6 | 0.000118073047858942 |               50816 |               50816 |             50816 |                 0 |                    0
   8 |  7 |       700 |     800 | 700-800   |                     |                     |                   |                   |                    |                  34814 |                  34814 |                34814 |                    0 |                     0 |               34814 |               34814 |             34814 |                 6 | 0.000172344459125639 |               34814 |               34814 |             34814 |                 4 | 0.000114896306083759
   9 |  8 |       800 |     900 | 800-900   |                     |                     |                   |                   |                    |                  23023 |                  23023 |                23023 |                    1 |  4.34348260435217e-05 |               23023 |               23023 |             23023 |                 4 | 0.000173739304174087 |               23023 |               23023 |             23023 |                 1 | 4.34348260435217e-05
  10 |  9 |       900 |    1000 | 900-1000  |                     |                     |                   |                   |                    |                  14215 |                  14215 |                14215 |                    1 |  7.03482237073514e-05 |               14215 |               14215 |             14215 |                 1 | 7.03482237073514e-05 |               14215 |               14215 |             14215 |                 5 | 0.000351741118536757
  11 | 10 |      1000 |    5000 | 1000-5000 |                     |                     |                   |                   |                    |                  23527 |                  23527 |                23527 |                    0 |                     0 |               23527 |               23527 |             23527 |                 0 |                    0 |               23527 |               23527 |             23527 |                 3 | 0.000127513070089684
(11 rows)

我尝试了以下2列(有效,但我不想为100列写5次,除了列数必须是参数):

SELECT d,c_1_avg_parcelcount,c_2_avg_parcelcount,
  (SELECT avg(c) FROM (VALUES (c_1_avg_parcelcount) , (c_2_avg_parcelcount) ) T (c)) AS Avg_,
  (SELECT sum(c) FROM (VALUES (c_1_avg_parcelcount) , (c_2_avg_parcelcount) ) T (c)) AS sum_
FROM   panel_stats_rnd;

我也尝试过以下但不起作用。

WITH cols AS (
    select value(column_name) from information_schema.columns
    where table_name = 'panel_stats_rnd'
          AND column_name SIMILAR TO 'c_%avg_parcelcount'
          AND column_name != 'called_avg_parcelcount'
)
SELECT *, (SELECT avg(Col) FROM cols V(Col) ) AS col_average
FROM   panel_stats_rnd;

我快到了,但有些东西不见了......

1 个答案:

答案 0 :(得分:2)

select
  *,
  (select avg(v::numeric)
     from json_each_text(row_to_json(panel_stats_rnd.*)) as j(k,v)
    where k like 'c\_%\_avg\_parcelcount') as rnd_avg_parcelcount,
  (select sum(v::numeric)
     from json_each_text(row_to_json(panel_stats_rnd.*)) as j(k,v)
    where k like 'c\_%\_sum\_parcelcount') as rnd_sum_parcelcount
from
  panel_stats_rnd;

查看有关所涉及功能的documentation

基础字符(\_)有转义符,因为对于like运算符,它意味着任何单个字符,例如select 'a' like '_';为{{1} }。