PostgreSQL根据两个变量计算面积比例
PostgreSQL calculate area proportion based on two variables
我对 PostgreSQL 比较陌生,无法真正解决一个简单的问题。以简化的table为例:
create table example(
objectid integer,
soil_type integer,
area double precision);
values (2,4,23.5),
(2,3,30.45),
(2,6,20.1),
(1,3,10.5),
(3,6,40.5),
(3,4,20);
如何计算每个对象 id 中每种土壤类型的面积份额?
这会根据 soil_type 进行简单的分组以获得每个 soil_type 的总和(面积),将其放入子查询中,然后计算总和以获得总面积:
select soil_type, area, area / sum(area) over () as proportion
from (select soil_type, sum(area) area from example group by soil_type)x;
soil_type | area | proportion
-----------+-------+---------------------
3 | 40.95 | 0.2823164426059979
4 | 43.5 | 0.29989658738366076
6 | 60.6 | 0.41778697001034126
你也可以这样做:
with x as (select soil_type, sum(area) area from example group by soil_type)
select soil_type, area, area / (SELECT sum(area) FROM x) as proportion from x;
您需要每个对象的面积总和。 - 但同时保留所有行。
这是通过 window 函数完成的:sum(area) OVER(PARTITION BY objectid)
。
- 或者,如果您需要每个 objectid 的份额 soil_type,PARTITION BY soil_type
.
SELECT
objectid,
soil_type,
area,
area / sum(area) OVER(PARTITION BY objectid) AS share
FROM example
ORDER BY 1,2;
输出:
objectid | soil_type | area | share
----------+-----------+-------+---------------------
1 | 3 | 10.5 | 1
2 | 3 | 30.45 | 0.41120864280891284
2 | 4 | 23.5 | 0.31735313977042534
2 | 6 | 20.1 | 0.2714382174206617
3 | 4 | 20 | 0.3305785123966942
3 | 6 | 40.5 | 0.6694214876033058
或:
SELECT
objectid,
soil_type,
area,
area / sum(area) OVER(PARTITION BY soil_type) AS share
FROM example
ORDER BY 1,2;
输出:
objectid | soil_type | area | share
----------+-----------+-------+---------------------
1 | 3 | 10.5 | 0.2564102564102564
2 | 3 | 30.45 | 0.7435897435897435
2 | 4 | 23.5 | 0.5402298850574713
2 | 6 | 20.1 | 0.3316831683168317
3 | 4 | 20 | 0.45977011494252873
3 | 6 | 40.5 | 0.6683168316831684
(6 rows)
我对 PostgreSQL 比较陌生,无法真正解决一个简单的问题。以简化的table为例:
create table example(
objectid integer,
soil_type integer,
area double precision);
values (2,4,23.5),
(2,3,30.45),
(2,6,20.1),
(1,3,10.5),
(3,6,40.5),
(3,4,20);
如何计算每个对象 id 中每种土壤类型的面积份额?
这会根据 soil_type 进行简单的分组以获得每个 soil_type 的总和(面积),将其放入子查询中,然后计算总和以获得总面积:
select soil_type, area, area / sum(area) over () as proportion
from (select soil_type, sum(area) area from example group by soil_type)x;
soil_type | area | proportion
-----------+-------+---------------------
3 | 40.95 | 0.2823164426059979
4 | 43.5 | 0.29989658738366076
6 | 60.6 | 0.41778697001034126
你也可以这样做:
with x as (select soil_type, sum(area) area from example group by soil_type)
select soil_type, area, area / (SELECT sum(area) FROM x) as proportion from x;
您需要每个对象的面积总和。 - 但同时保留所有行。
这是通过 window 函数完成的:sum(area) OVER(PARTITION BY objectid)
。
- 或者,如果您需要每个 objectid 的份额 soil_type,PARTITION BY soil_type
.
SELECT
objectid,
soil_type,
area,
area / sum(area) OVER(PARTITION BY objectid) AS share
FROM example
ORDER BY 1,2;
输出:
objectid | soil_type | area | share
----------+-----------+-------+---------------------
1 | 3 | 10.5 | 1
2 | 3 | 30.45 | 0.41120864280891284
2 | 4 | 23.5 | 0.31735313977042534
2 | 6 | 20.1 | 0.2714382174206617
3 | 4 | 20 | 0.3305785123966942
3 | 6 | 40.5 | 0.6694214876033058
或:
SELECT
objectid,
soil_type,
area,
area / sum(area) OVER(PARTITION BY soil_type) AS share
FROM example
ORDER BY 1,2;
输出:
objectid | soil_type | area | share
----------+-----------+-------+---------------------
1 | 3 | 10.5 | 0.2564102564102564
2 | 3 | 30.45 | 0.7435897435897435
2 | 4 | 23.5 | 0.5402298850574713
2 | 6 | 20.1 | 0.3316831683168317
3 | 4 | 20 | 0.45977011494252873
3 | 6 | 40.5 | 0.6683168316831684
(6 rows)