如何获得 PostgreSQL 中两个平均值之间的差异,其中平均值在一列上,最终 table 按两列分组?
How to get difference between two average values in PostgreSQL, where the averages are on a column, and the final table grouped by two columns?
我想知道 value
的两个平均值之间的区别,其中每个平均值都按条件 isCool
过滤为 True
或 False
,并且最终结果按 town
和 season
分组,例如
table
| id | value | isCool | town | season |
|----|-------|--------|--------|--------|
| 0 | 1 | True | TownA | spring |
| 1 | 2 | False | TownA | winter |
| 2 | 3 | True | TownB | spring |
| 3 | 4 | False | TownA | winter |
| 4 | 5 | False | TownB | spring |
| 5 | 6 | True | TownB | winter |
我想结束 table:
| category | difference_of_is_cool_averages |
|----------|--------------------------------|
| TownA | 2 | <-- ABS(1 - (2 + 4)/2)
| TownB | 0.5 | <-- ABS(5 - (3 + 6)/2)
| spring | 3 | <-- ABS(5 - (3 + 1)/2)
| winter | 3 | <-- ABS(6 - (4 + 2)/2)
我已经尝试过了,但不幸的是,我的 PostgreSQL 技能有限,我根本没有走多远。我试过了
SELECT
AVG(value), town
(SELECT id, value, town, season
FROM table
WHERE isCool = 'True') AS TableSummary1
GROUP BY town;
但这与我想要的相去甚远。有人可以帮忙吗?这甚至可以用 PostgreSQL 实现吗?
您可以逆轴旋转,然后计算每组的两个条件平均值之间的差异:
select x.category,
abs(avg(t.value) filter(where not t.iscool) - avg(t.value) filter(where t.iscool)) diff
from mytable t
cross join lateral (values (town), (season)) as x(category)
group by x.category
如果您希望能够按照所需结果对结果集进行排序,那么我们需要跟踪原始列:
select x.category,
abs(avg(t.value) filter(where not t.iscool) - avg(t.value) filter(where t.iscool)) diff
from mytable t
cross join lateral (values (town, 1), (season, 2)) as x(category, grp)
group by x.category, x.grp
order by x.grp
category | diff
:------- | ---------------------:
TownB | 0.5000000000000000
TownA | 2.00000000000000000000
winter | 3.0000000000000000
spring | 3.0000000000000000
这里Union All
会帮助你。简单地通过分组 town
然后通过分组 season
并合并它们来计算一次平均值的差异。您可以像下面这样写您的查询:
select
town "Category",
round(abs(avg(value) filter (where iscool='t') - avg(value) filter (where iscool='f')),2) "difference_of_is_cool_averages"
from town
group by town
union all
select
season,
round(abs(avg(value) filter (where iscool='t') - avg(value) filter (where iscool='f')),2)
from town
group by season
我想知道 value
的两个平均值之间的区别,其中每个平均值都按条件 isCool
过滤为 True
或 False
,并且最终结果按 town
和 season
分组,例如
table
| id | value | isCool | town | season |
|----|-------|--------|--------|--------|
| 0 | 1 | True | TownA | spring |
| 1 | 2 | False | TownA | winter |
| 2 | 3 | True | TownB | spring |
| 3 | 4 | False | TownA | winter |
| 4 | 5 | False | TownB | spring |
| 5 | 6 | True | TownB | winter |
我想结束 table:
| category | difference_of_is_cool_averages |
|----------|--------------------------------|
| TownA | 2 | <-- ABS(1 - (2 + 4)/2)
| TownB | 0.5 | <-- ABS(5 - (3 + 6)/2)
| spring | 3 | <-- ABS(5 - (3 + 1)/2)
| winter | 3 | <-- ABS(6 - (4 + 2)/2)
我已经尝试过了,但不幸的是,我的 PostgreSQL 技能有限,我根本没有走多远。我试过了
SELECT
AVG(value), town
(SELECT id, value, town, season
FROM table
WHERE isCool = 'True') AS TableSummary1
GROUP BY town;
但这与我想要的相去甚远。有人可以帮忙吗?这甚至可以用 PostgreSQL 实现吗?
您可以逆轴旋转,然后计算每组的两个条件平均值之间的差异:
select x.category,
abs(avg(t.value) filter(where not t.iscool) - avg(t.value) filter(where t.iscool)) diff
from mytable t
cross join lateral (values (town), (season)) as x(category)
group by x.category
如果您希望能够按照所需结果对结果集进行排序,那么我们需要跟踪原始列:
select x.category,
abs(avg(t.value) filter(where not t.iscool) - avg(t.value) filter(where t.iscool)) diff
from mytable t
cross join lateral (values (town, 1), (season, 2)) as x(category, grp)
group by x.category, x.grp
order by x.grp
category | diff :------- | ---------------------: TownB | 0.5000000000000000 TownA | 2.00000000000000000000 winter | 3.0000000000000000 spring | 3.0000000000000000
这里Union All
会帮助你。简单地通过分组 town
然后通过分组 season
并合并它们来计算一次平均值的差异。您可以像下面这样写您的查询:
select
town "Category",
round(abs(avg(value) filter (where iscool='t') - avg(value) filter (where iscool='f')),2) "difference_of_is_cool_averages"
from town
group by town
union all
select
season,
round(abs(avg(value) filter (where iscool='t') - avg(value) filter (where iscool='f')),2)
from town
group by season