Sql 按组聚合Postgres中的存储

Sql 按组聚合Postgres中的存储,sql,postgresql,postgresql-9.5,Sql,Postgresql,Postgresql 9.5,我有这样一个hstore的数据: |brand|account|likes|views | |-----|-------|-----|----------------------| |Ford |ford_uk|1 |"3"=>"100" | |Ford |ford_us|2 |"3"=>"200", "5"=>"10" | |Jeep |jeep_uk|3 |"3"=>"300"

我有这样一个hstore的数据:

|brand|account|likes|views                 | 
|-----|-------|-----|----------------------|
|Ford |ford_uk|1    |"3"=>"100"            |
|Ford |ford_us|2    |"3"=>"200", "5"=>"10" |
|Jeep |jeep_uk|3    |"3"=>"300"            |
|Jeep |jeep_us|4    |"3"=>"400", "5"=>"20" |
我希望能够按键、按品牌对商店进行汇总:

|brand|likes|views                 | 
|-----|-----|----------------------|
|Ford |3    |"3"=>"300", "5"=>"10" |
|Jeep |7    |"3"=>"700", "5"=>"20" |
提供了一个很好的解决方案,说明如何在没有分组的情况下执行此操作。使其适应这种情况会产生如下结果:

SELECT
  sum(likes) AS total_likes,
 (SELECT hstore(array_agg(key), array_agg(value::text))
  FROM (
    SELECT s.key, sum(s.value::integer)
    FROM (
      SELECT((each(views)).*)
    ) AS s(key, value)
    GROUP BY key
  ) x(key, value)) AS total_views
FROM my_table
GROUP BY brand
然而,这就产生了:

错误:子查询使用外部查询中未分组的列“my_table.views”


感谢您的帮助

这是因为在
分组依据
查询中使用的
视图
列没有聚合函数。
非常快速的解决方法:

with my_table(brand,account,likes,views) as (
  values
    ('Ford', 'ford_uk', 1, '"3"=>"100"'::hstore),
    ('Ford', 'ford_uk', 2, '"3"=>"200", "5"=>"10"'),
    ('Jeep', 'jeep_uk', 3, '"3"=>"300"'::hstore),
    ('Jeep', 'jeep_uk', 4, '"3"=>"400", "5"=>"20"'))
SELECT
  brand,
  sum(likes) AS total_likes,
 (SELECT hstore(array_agg(key), array_agg(value::text))
  FROM (
    SELECT s.key, sum(s.value::integer)
    FROM 
      unnest(array_agg(views)) AS h, --<< aggregate views according to the group by, then unnest it into the table
      each(h) as s(key,value)
    GROUP BY key
  ) x(key, value)) AS total_views
FROM my_table
GROUP BY brand
之后,您的查询将更简单、更“规范”:

更新2

即使没有
create aggregate
,函数
hstore\u sum\u ffunc
也可能有用:

select
  brand, 
  sum(likes) as total_likes,
  hstore_sum_ffunc(array_agg(views)) as total_views
from my_table
group by brand;

这是因为在
分组依据
查询中使用的
视图
列没有聚合函数。
非常快速的解决方法:

with my_table(brand,account,likes,views) as (
  values
    ('Ford', 'ford_uk', 1, '"3"=>"100"'::hstore),
    ('Ford', 'ford_uk', 2, '"3"=>"200", "5"=>"10"'),
    ('Jeep', 'jeep_uk', 3, '"3"=>"300"'::hstore),
    ('Jeep', 'jeep_uk', 4, '"3"=>"400", "5"=>"20"'))
SELECT
  brand,
  sum(likes) AS total_likes,
 (SELECT hstore(array_agg(key), array_agg(value::text))
  FROM (
    SELECT s.key, sum(s.value::integer)
    FROM 
      unnest(array_agg(views)) AS h, --<< aggregate views according to the group by, then unnest it into the table
      each(h) as s(key,value)
    GROUP BY key
  ) x(key, value)) AS total_views
FROM my_table
GROUP BY brand
之后,您的查询将更简单、更“规范”:

更新2

即使没有
create aggregate
,函数
hstore\u sum\u ffunc
也可能有用:

select
  brand, 
  sum(likes) as total_likes,
  hstore_sum_ffunc(array_agg(views)) as total_views
from my_table
group by brand;

如果为
hstore
创建一个聚合,这会变得更容易:

create aggregate hstore_agg(hstore) 
(
  sfunc = hs_concat(hstore, hstore),
  stype = hstore
);
然后你可以这样做:

with totals as (
  select t1.brand,
         hstore(k, sum(v::int)::text) as views
  from my_table t1, each(views) x(k,v)
  group by brand, k
) 
select brand, 
       (select sum(likes) from my_table t2 where t1.brand = t2.brand) as likes, 
       hstore_agg(views) as views
from totals t1
group by brand;
另一个选项是将可能较慢的相关子查询移动到CTE中:

with vals as (
  select t1.brand,
         hstore(k, sum(v::int)::text) as views
  from my_table t1, each(views) x(k,v)
  group by brand, k
), view_totals as (
  select brand, 
         hstore_agg(views) as views
  from vals
  group by brand
), like_totals as (
  select brand, 
         sum(likes) as likes
  from my_table
  group by brand
)
select vt.brand, 
       lt.likes,
       vt.views
from view_totals vt
  join like_totals lt on vt.brand = lt.brand
order by brand;

如果为
hstore
创建一个聚合,这会变得更容易:

create aggregate hstore_agg(hstore) 
(
  sfunc = hs_concat(hstore, hstore),
  stype = hstore
);
然后你可以这样做:

with totals as (
  select t1.brand,
         hstore(k, sum(v::int)::text) as views
  from my_table t1, each(views) x(k,v)
  group by brand, k
) 
select brand, 
       (select sum(likes) from my_table t2 where t1.brand = t2.brand) as likes, 
       hstore_agg(views) as views
from totals t1
group by brand;
另一个选项是将可能较慢的相关子查询移动到CTE中:

with vals as (
  select t1.brand,
         hstore(k, sum(v::int)::text) as views
  from my_table t1, each(views) x(k,v)
  group by brand, k
), view_totals as (
  select brand, 
         hstore_agg(views) as views
  from vals
  group by brand
), like_totals as (
  select brand, 
         sum(likes) as likes
  from my_table
  group by brand
)
select vt.brand, 
       lt.likes,
       vt.views
from view_totals vt
  join like_totals lt on vt.brand = lt.brand
order by brand;