9

私はこのようなテーブルを持っています:

                         Table "public.statistics"

id         | integer                | not null default nextval('statistics_id_seq'::regclass)
goals      | hstore                 | 

アイテム:

|id    |goals                  |
|30059 |"3"=>"123"             |
|27333 |"3"=>"200", "5"=>"10"  |

ハッシュのキーですべての値を集計するにはどうすればよいですか?

私はこのような結果を得たいです:

select sum(goals) from statistics

戻る

|goals                 |
|"3"=>"323", "5"=>"10" |
4

2 に答える 2

15

ローレンスの答えに基づいて、合計されたキーと値のペアを新しいhstoreusingarray_agghstore(text[], text[])コンストラクターに集約する純粋な SQL の方法を次に示します。

http://sqlfiddle.com/#!1/9f1fb/17

SELECT hstore(array_agg(hs_key), array_agg(hs_value::text))
FROM (
  SELECT
    s.hs_key, sum(s.hs_value::integer)
  FROM (
    SELECT (each(goals)).* FROM statistics
  ) as s(hs_key, hs_value)
  GROUP BY hs_key
) x(hs_key,hs_value)

to_numberまた、整数への単純なキャストに置き換え、キーと値の繰り返しを簡素化しました。

于 2012-10-23T00:09:17.783 に答える
5

数値変換を回避するためにこれを行う方法があるかもしれませんが、これで仕事が完了するはずです:

SELECT 
  key, Sum(to_number(value, '999999999999')) FROM (
  SELECT (each(goals)).key, (each(goals)).value FROM public.statistics
) as s
Group By
  key

http://sqlfiddle.com/#!1/eb745/10/0

これは、Postgres がこのように曲げたくない大きな臭いですが、次のようになります。

create table test (id int, goals hstore);

Insert Into Test(id, goals) Values (30059, '3=>123');
Insert Into Test(id, goals) Values (27333, '3=>200,5=>10');

Create Function hagg() returns hstore As 
'Declare ret hstore := ('''' :: hstore); i hstore; c cursor for Select hstore(key, (x.Value::varchar)) From (Select key, Sum((s.value::int)) as Value From (Select (each(goals)).* From Test) as s Group By key) as x; BEGIN Open c; Loop Fetch c into i; Exit When Not FOUND; ret := i || ret; END LOOP; return ret; END' Language 'plpgsql';

SQL フィドルで複数行の関数本体を受け入れることができませんでした。実際の postgres では、これを $$ で引用して少し分割できるはずです。

http://sqlfiddle.com/#!1/e2ea7/1/0

于 2012-10-22T21:50:27.993 に答える