PostgresQL 中每个类别的降雨量系列
Rainfall ranged series for each category in PostgresSQL
我们有 POPULATION
和 AGE_GROUP
tables.
Table : POPULATION
条目如下。
village
age_group
male_count
female_count
A
0-4
4
2
A
5-9
3
4
A
10-14
4
9
A
15-19
8
6
A
25-29
8
6
像这样,我们有多个名为 A, B, C, D etc
.
的村庄的每个年龄组的条目(很少有年龄组缺失,比如缺失 20-24
)
Table : AGE_GROUP
条目如下
age_group
min_age
max_age
0-4
0
4
5-9
5
9
10-14
10
14
15-19
15
19
20-24
20
24
25-29
25
29
30-34
30
34
35-39
35
39
40-44
40
44
45-49
45
49
50-54
50
54
55-59
55
59
60-64
60
64
65-69
65
69
70-74
70
74
75-79
75
79
80-84
80
84
85-89
85
89
90-94
90
94
95-99
95
99
100 above
100
150
没有每个村庄的少数年龄组的统计数据。要求是显示 zero
年龄组,这些年龄组在 postgres 查询中的相应村庄中不存在。
在单个村庄的情况下,我们可以将 POPULATION
table 与 AGE_GROUP
table 左连接,并可以使用 COALESCE()
函数来填充缺失的统计数据如下
SELECT
village,
age_group,
COALESCE(male_count, 0) AS male_count,
COALESCE(female_count, 0) AS female_count
FROM
AGE_GROUP ag
LEFT JOIN
POPULATION p
ON
p.age_group = ag.age_group
以上查询仅在我们只有一个村庄时有效(假设使用 COALESEC(village, 'A') as village
)。但是,我们有多个村庄,每个村庄都缺少不同的年龄段。
你可以先cross join所有有ag的村庄table
CREATE TABLE POPULATION (
"village" VARCHAR(1),
"age_group" VARCHAR(5),
"male_count" INTEGER,
"female_count" INTEGER
);
INSERT INTO POPULATION
("village", "age_group", "male_count", "female_count")
VALUES
('A', '0-4', '4', '2'),
('A', '5-9', '3', '4'),
('A', '10-14', '4', '9'),
('A', '15-19', '8', '6'),
('A', '25-29', '8', '6'),
('B', '0-4', '4', '2'),
('B', '5-9', '3', '4'),
('B', '60-64', '4', '9'),
('B', '15-19', '8', '6'),
('B', '25-29', '8', '6');
CREATE TABLE AGE_GROUP (
"age_group" VARCHAR(9),
"min_age" INTEGER,
"max_age" INTEGER
);
INSERT INTO AGE_GROUP
("age_group", "min_age", "max_age")
VALUES
('0-4', '0', '4'),
('5-9', '5', '9'),
('10-14', '10', '14'),
('15-19', '15', '19'),
('20-24', '20', '24'),
('25-29', '25', '29'),
('30-34', '30', '34'),
('35-39', '35', '39'),
('40-44', '40', '44'),
('45-49', '45', '49'),
('50-54', '50', '54'),
('55-59', '55', '59'),
('60-64', '60', '64'),
('65-69', '65', '69'),
('70-74', '70', '74'),
('75-79', '75', '79'),
('80-84', '80', '84'),
('85-89', '85', '89'),
('90-94', '90', '94'),
('95-99', '95', '99'),
('100 above', '100', '150');
WITH CTE AS (SELECT DISTINCT "village", ag.* FROM POPULATION CROSS JOIN AGE_GROUP ag)
SELECT DISTINCT
ag.village,
ag.age_group,
COALESCE(male_count, 0) AS male_count,
COALESCE(female_count, 0) AS female_count
FROM
CTE ag
LEFT JOIN
POPULATION p
ON p."village" = ag."village" AND
p.age_group = ag.age_group
village | age_group | male_count | female_count
:------ | :-------- | ---------: | -----------:
A | 0-4 | 4 | 2
A | 100 above | 0 | 0
A | 10-14 | 4 | 9
A | 15-19 | 8 | 6
A | 20-24 | 0 | 0
A | 25-29 | 8 | 6
A | 30-34 | 0 | 0
A | 35-39 | 0 | 0
A | 40-44 | 0 | 0
A | 45-49 | 0 | 0
A | 50-54 | 0 | 0
A | 55-59 | 0 | 0
A | 5-9 | 3 | 4
A | 60-64 | 0 | 0
A | 65-69 | 0 | 0
A | 70-74 | 0 | 0
A | 75-79 | 0 | 0
A | 80-84 | 0 | 0
A | 85-89 | 0 | 0
A | 90-94 | 0 | 0
A | 95-99 | 0 | 0
B | 0-4 | 4 | 2
B | 100 above | 0 | 0
B | 10-14 | 0 | 0
B | 15-19 | 8 | 6
B | 20-24 | 0 | 0
B | 25-29 | 8 | 6
B | 30-34 | 0 | 0
B | 35-39 | 0 | 0
B | 40-44 | 0 | 0
B | 45-49 | 0 | 0
B | 50-54 | 0 | 0
B | 55-59 | 0 | 0
B | 5-9 | 3 | 4
B | 60-64 | 4 | 9
B | 65-69 | 0 | 0
B | 70-74 | 0 | 0
B | 75-79 | 0 | 0
B | 80-84 | 0 | 0
B | 85-89 | 0 | 0
B | 90-94 | 0 | 0
B | 95-99 | 0 | 0
db<>fiddle here
我们有 POPULATION
和 AGE_GROUP
tables.
Table : POPULATION
条目如下。
village | age_group | male_count | female_count |
---|---|---|---|
A | 0-4 | 4 | 2 |
A | 5-9 | 3 | 4 |
A | 10-14 | 4 | 9 |
A | 15-19 | 8 | 6 |
A | 25-29 | 8 | 6 |
像这样,我们有多个名为 A, B, C, D etc
.
20-24
)
Table : AGE_GROUP
条目如下
age_group | min_age | max_age |
---|---|---|
0-4 | 0 | 4 |
5-9 | 5 | 9 |
10-14 | 10 | 14 |
15-19 | 15 | 19 |
20-24 | 20 | 24 |
25-29 | 25 | 29 |
30-34 | 30 | 34 |
35-39 | 35 | 39 |
40-44 | 40 | 44 |
45-49 | 45 | 49 |
50-54 | 50 | 54 |
55-59 | 55 | 59 |
60-64 | 60 | 64 |
65-69 | 65 | 69 |
70-74 | 70 | 74 |
75-79 | 75 | 79 |
80-84 | 80 | 84 |
85-89 | 85 | 89 |
90-94 | 90 | 94 |
95-99 | 95 | 99 |
100 above | 100 | 150 |
没有每个村庄的少数年龄组的统计数据。要求是显示 zero
年龄组,这些年龄组在 postgres 查询中的相应村庄中不存在。
在单个村庄的情况下,我们可以将 POPULATION
table 与 AGE_GROUP
table 左连接,并可以使用 COALESCE()
函数来填充缺失的统计数据如下
SELECT
village,
age_group,
COALESCE(male_count, 0) AS male_count,
COALESCE(female_count, 0) AS female_count
FROM
AGE_GROUP ag
LEFT JOIN
POPULATION p
ON
p.age_group = ag.age_group
以上查询仅在我们只有一个村庄时有效(假设使用 COALESEC(village, 'A') as village
)。但是,我们有多个村庄,每个村庄都缺少不同的年龄段。
你可以先cross join所有有ag的村庄table
CREATE TABLE POPULATION ( "village" VARCHAR(1), "age_group" VARCHAR(5), "male_count" INTEGER, "female_count" INTEGER ); INSERT INTO POPULATION ("village", "age_group", "male_count", "female_count") VALUES ('A', '0-4', '4', '2'), ('A', '5-9', '3', '4'), ('A', '10-14', '4', '9'), ('A', '15-19', '8', '6'), ('A', '25-29', '8', '6'), ('B', '0-4', '4', '2'), ('B', '5-9', '3', '4'), ('B', '60-64', '4', '9'), ('B', '15-19', '8', '6'), ('B', '25-29', '8', '6');
CREATE TABLE AGE_GROUP ( "age_group" VARCHAR(9), "min_age" INTEGER, "max_age" INTEGER ); INSERT INTO AGE_GROUP ("age_group", "min_age", "max_age") VALUES ('0-4', '0', '4'), ('5-9', '5', '9'), ('10-14', '10', '14'), ('15-19', '15', '19'), ('20-24', '20', '24'), ('25-29', '25', '29'), ('30-34', '30', '34'), ('35-39', '35', '39'), ('40-44', '40', '44'), ('45-49', '45', '49'), ('50-54', '50', '54'), ('55-59', '55', '59'), ('60-64', '60', '64'), ('65-69', '65', '69'), ('70-74', '70', '74'), ('75-79', '75', '79'), ('80-84', '80', '84'), ('85-89', '85', '89'), ('90-94', '90', '94'), ('95-99', '95', '99'), ('100 above', '100', '150');
WITH CTE AS (SELECT DISTINCT "village", ag.* FROM POPULATION CROSS JOIN AGE_GROUP ag) SELECT DISTINCT ag.village, ag.age_group, COALESCE(male_count, 0) AS male_count, COALESCE(female_count, 0) AS female_count FROM CTE ag LEFT JOIN POPULATION p ON p."village" = ag."village" AND p.age_group = ag.age_group
village | age_group | male_count | female_count :------ | :-------- | ---------: | -----------: A | 0-4 | 4 | 2 A | 100 above | 0 | 0 A | 10-14 | 4 | 9 A | 15-19 | 8 | 6 A | 20-24 | 0 | 0 A | 25-29 | 8 | 6 A | 30-34 | 0 | 0 A | 35-39 | 0 | 0 A | 40-44 | 0 | 0 A | 45-49 | 0 | 0 A | 50-54 | 0 | 0 A | 55-59 | 0 | 0 A | 5-9 | 3 | 4 A | 60-64 | 0 | 0 A | 65-69 | 0 | 0 A | 70-74 | 0 | 0 A | 75-79 | 0 | 0 A | 80-84 | 0 | 0 A | 85-89 | 0 | 0 A | 90-94 | 0 | 0 A | 95-99 | 0 | 0 B | 0-4 | 4 | 2 B | 100 above | 0 | 0 B | 10-14 | 0 | 0 B | 15-19 | 8 | 6 B | 20-24 | 0 | 0 B | 25-29 | 8 | 6 B | 30-34 | 0 | 0 B | 35-39 | 0 | 0 B | 40-44 | 0 | 0 B | 45-49 | 0 | 0 B | 50-54 | 0 | 0 B | 55-59 | 0 | 0 B | 5-9 | 3 | 4 B | 60-64 | 4 | 9 B | 65-69 | 0 | 0 B | 70-74 | 0 | 0 B | 75-79 | 0 | 0 B | 80-84 | 0 | 0 B | 85-89 | 0 | 0 B | 90-94 | 0 | 0 B | 95-99 | 0 | 0
db<>fiddle here