POSTGRES 9.6:如何在单个查询中对 table 的每一列的百分比进行分解?

POSTGRES 9.6: How do I make a disaggregation in percentages of each column of a table on a single query?

我有一个 table 存储用户点击信息,例如 "so"、"browser"、"timezone"。我需要对每一列进行分解以构建每一列的饼图。我需要一个 json 这样的结果:

{"results": {
              "browser":[{"name":"Chrome","qty":50,"percentage:"50"},
                         {"name":"Firefox","qty":50,"percentage:"50"}], "SO":[{"name":"Linux","qty":50,"percentage:"50"},{"name":"WIndows","qty":50,"percentage:"50"}]} }

table定义为:

=================================
TABLE DEFINITION
=================================

Column  Type    Comment
sponsor_ad_click_id integer Auto Increment [nextval('ad_clicks_ad_click_id_seq')]    
sponsor_ad_id   integer  
clicked_date    timestamptz  
browser text NULL    
os  text NULL    
device  text NULL    
continent_code  text NULL    
continent_name  text NULL    
country_code    text NULL    
country_name    text NULL    
timezone    text NULL    
ip  text NULL    
social_network_id   smallint NULL [1]    
sponsor_id  integer  

我尝试过子查询,但我只能 return 每个子查询中的一个值,

  SELECT (select count(spac2.browser) FROM sponsor_ad_clicks spac2 where spac2.sponsor_ad_id = spac.sponsor_ad_id),
                     (select count(spac2.os) FROM sponsor_ad_clicks spac2 wheer spac2.sponsor_ad_id = spac.sponsor_ad_id),
                     (select count(spac2.device) FROM sponsor_ad_clicks spac2 where spac2.sponsor_ad_id = spac.sponsor_ad_id),
                     (select count(spac2.continent_name) FROM sponsor_ad_clicks spac2 where spac2.sponsor_ad_id = spac.sponsor_ad_id),
                     (select count(spac2.country_name) FROM sponsor_ad_clicks spac2 where spac2.sponsor_ad_id = spac.sponsor_ad_id),
                     (select count(spac2.timezone) FROM sponsor_ad_clicks spac2 where spac2.sponsor_ad_id = spac.sponsor_ad_id)
              FROM sponsor_ad_clicks spac
              WHERE spac.sponsor_ad_id = 2

这显然是不正确的,因为它 return 每个子查询只有一个值,

我也试过构建一个 json 数组,但没有成功,有什么想法吗?

这不是一个完整的解决方案,但更多的是提示移动到哪里。我聚合在浏览器列上。您的问题中的时间太晚且缺少数据样本使我只能这样做。无论如何,要添加另一个指标,只需 partition over column_name 并将其添加到内置 json。此外,您可能希望使用 json_build 而不是 concat 和强制转换。再次 - 您的问题缺少信息...

t=# \pset format unaligned
Output format is unaligned.
t=# with j as (
  with agg as (
    select distinct
      count(1) over (partition by browser) qty
    , browser
    , count(1) over (partition by true) total
    from sponsor_ad_clicks
  )
  select
    browser as "name"
  , qty
  , qty*100/total percentage
  from agg
)
select
  jsonb_pretty(concat('{"result":{"browser":',array_to_json(array_agg(to_json(j))),'}}')::jsonb) r
from j
;
r
{
    "result": {
        "browser": [
            {
                "qty": 2,
                "name": "chrome",
                "percentage": 40
            },
            {
                "qty": 3,
                "name": "ie",
                "percentage": 60
            }
        ]
    }
}
(1 row)