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)
我有一个 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)