1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
| -- 原数据 +-----------+-----------+ | age_class | age_range | +-----------+-----------+ | 1 | 21-30岁 | | 2 | 31-40岁 | | 3 | 41-50岁 | +-----------+-----------+ +--------+-----+ | sex_cd | sex | +--------+-----+ | m | 男 | | f | 女 | +--------+-----+ +-----------+-----------+--------+------------+ | pref_name | age_class | sex_cd | population | +-----------+-----------+--------+------------+ | 秋田 | 1 | m | 400 | | 秋田 | 3 | m | 1000 | | 秋田 | 1 | f | 800 | | 秋田 | 3 | f | 1000 | | 青森 | 1 | m | 700 | | 青森 | 1 | f | 500 | | 青森 | 3 | f | 800 | | 东京 | 1 | m | 900 | | 东京 | 1 | f | 1500 | | 东京 | 3 | m | 900 | | 千叶 | 1 | m | 900 | | 千叶 | 1 | f | 1000 | | 千叶 | 3 | f | 900 | +-----------+-----------+--------+------------+ -- 预期结果 +-----------+--------+-----------+--------+--------+--------+ | age_class | sex_cd | age_class | sex_cd | 东北 | 关东 | +-----------+--------+-----------+--------+--------+--------+ | 1 | m | 1 | m | 1100 | 1800 | | 1 | f | 1 | f | 1300 | 2500 | | 2 | m | NULL | NULL | NULL | NULL | | 2 | f | NULL | NULL | NULL | NULL | | 3 | m | 3 | m | 1000 | 900 | | 3 | f | 3 | f | 1800 | 900 | +-----------+--------+-----------+--------+--------+--------+ -- 先按年龄阶层和性别做分组查询 select age_class, sex_cd, sum(case when pref_name in ('青森', '秋田') then population else 0 end) as '东北', sum(case when pref_name in ('东京', '千叶') then population else 0 end) as '关东' from `TblPop` group by age_class, sex_cd; +-----------+--------+--------+--------+ | age_class | sex_cd | 东北 | 关东 | +-----------+--------+--------+--------+ | 1 | f | 1300 | 2500 | | 1 | m | 1100 | 1800 | | 3 | f | 1800 | 900 | | 3 | m | 1000 | 900 | +-----------+--------+--------+--------+ -- 再拿查询后的结果和年龄阶层表和性别表做表链接 select * from ..... as p left join TblSex as s on s.sex_cd=p.sex_cd left join TblAge as a on a.age_class=p.age_class; +-----------+--------+--------+--------+--------+------+-----------+-----------+ | age_class | sex_cd | 东北 | 关东 | sex_cd | sex | age_class | age_range | +-----------+--------+--------+--------+--------+------+-----------+-----------+ | 1 | m | 1100 | 1800 | m | 男 | 1 | 21-30岁 | | 1 | f | 1300 | 2500 | f | 女 | 1 | 21-30岁 | | 3 | m | 1000 | 900 | m | 男 | 3 | 41-50岁 | | 3 | f | 1800 | 900 | f | 女 | 3 | 41-50岁 | +-----------+--------+--------+--------+--------+------+-----------+-----------+ -- 但是没有出现age_class=2的数据,因为TblPop没有age_class=2的数据 -- 若想展示age_class=2的数据,可先让TblAge与TblSex做交叉连接,再与TblPop连接 select * from (select age_class, sex_cd from TblSex cross join TblAge) as master left join (select age_class, sex_cd, sum(case when pref_name in ('青森', '秋田') then population else 0 end) as '东北', sum(case when pref_name in ('东京', '千叶') then population else 0 end) as '关东' from `TblPop` group by age_class,sex_cd ) as p on p.age_class=Master.age_class and p.sex_cd=Master.sex_cd; +-----------+--------+-----------+--------+--------+--------+ | age_class | sex_cd | age_class | sex_cd | 东北 | 关东 | +-----------+--------+-----------+--------+--------+--------+ | 1 | m | 1 | m | 1100 | 1800 | | 1 | f | 1 | f | 1300 | 2500 | | 2 | m | NULL | NULL | NULL | NULL | | 2 | f | NULL | NULL | NULL | NULL | | 3 | m | 3 | m | 1000 | 900 | | 3 | f | 3 | f | 1800 | 900 | +-----------+--------+-----------+--------+--------+--------+
|