上一篇我们学习了如何利用 GROUP BY 子句与聚合函数实现数据的分组汇总。到此为止,我们已经完成了基础篇的学习。
本篇我们以世界银行公布的全球 GDP 和人口数据为案例,介绍使用 SQL 进行数据分析的常用方法。同时也作为对基础篇所学内容的回顾和复习。
GDP(国内生产总值)是指按市场价格计算的一个国家/地区所有常住单位在一定时期内生产活动的所有最终产品和服务的市场价格。GDP 通常被公认为是衡量国家/地区经济状况的最佳指标。
本文数据来源为世界银行公开数据中的 GDP(现价美元)和人口总数。为了方便使用,我们将数据转换成了 SQL 脚本,摘取了全球 217 个国家和地区 2010-2018 年的 GDP 数据(按照现价美元进行换算)以及相应的人口数据。案例的初始化脚本 gdp_data.sql 放在了 GitHub 上,可以点击链接进行下载。

初步探索数据

所有的 GDP 和人口数据都存储在 gdp_data 表中,我们先熟悉一下该表中的数据:

  1. SELECT * FROM gdp_data;


复制
该查询的结果如下(显示部分内容):
image.png
该表包含了 4 个字段:国家/地区名称、年度、人口以及 GDP。接下来统计一下表中包含的行数:

  1. SELECT COUNT(*) FROM gdp_data;
  2. COUNT(*)|
  3. --------|
  4. 1953|

复制
该表中共计有 1953 条数据。再按照国家/地区进行统计:

  1. SELECT country_name AS "国家/地区", COUNT(*) AS "数据量" FROM gdp_data GROUP BY country_name;

查询的结果如下(显示部分内容):
image.png
共计有 217 个国家/地区,每个国家/地区有 9 条数据。试试按照年度进行统计:

  1. SELECT year AS "年度", COUNT(*) AS "数据量" FROM gdp_data GROUP BY year;

年度统计的结果如下:
image.png
表中总共有 9 年的数据,每个年度包含 217 个国家/地区的数据。
如果想要查看具体国家/地区或者年度的数据,可以通过查询条件实现过滤。以下语句查询中国大陆 2018 年度的数据:

  1. SELECT * FROM gdp_data WHERE country_name = '中国' AND year = 2018;
  2. country_name|year|population|gdp |
  3. ------------|----|----------|-----------------|
  4. 中国 |2018|1392730000|13608200000000.00|

2018 年中国大陆将近有 14 亿人口,GDP 约为 13.6 万亿美元。
在进一步分析之前,需要确认数据中是否存在缺失值。

查找缺失值

以下查询可以统计人口和 GDP 缺失的记录数:

  1. SELECT COUNT(*) - COUNT(population) AS "人口数据缺失",
  2. COUNT(*) - COUNT(gdp) AS "GDP 数据缺失"
  3. FROM gdp_data;
  4. 人口数据缺失|GDP 数据缺失|
  5. ----------|-----------|
  6. 7| 131|

看看具体哪些记录缺失:

  1. SELECT * FROM gdp_data WHERE population IS NULL OR gdp IS NULL;

该查询的结果如下(显示部分内容):
image.png
缺失是由于没有统计或者公布相应的数据,我们在后续的分析过程中需要注意空值的处理。例如,在分析之前过滤掉这些无效的数据。

数据汇总

通过汇总可以对全球总人口和 GDP 数据进行整体了解。以下查询统计了 2018 年的数据:

  1. SELECT SUM(population) AS "总人口",
  2. ROUND(AVG(population),0) AS "平均人口",
  3. MAX(population) AS "最多人口",
  4. MIN(population) AS "最少人口"
  5. FROM gdp_data WHERE year = 2018;
  6. 总人口 |平均人口 |最多人口 |最少人口|
  7. ----------|-------------|----------|------|
  8. 7567243296|35033534 |1392730000| 11508|

复制
结果显示 2018 全球人数已经超过 75 亿。其中,ROUND 函数用于对数据进行取整。
再看一下 2018 年的 GDP 数据:

  1. SELECT SUM(gdp) AS "全球 GDP",
  2. ROUND(AVG(gdp),2) AS "平均 GDP",
  3. MAX(gdp) AS "最高 GDP",
  4. MIN(gdp) AS "最低 GDP"
  5. FROM gdp_data WHERE year = 2018;
  6. 全球 GDP |平均 GDP |最高 GDP |最低 GDP |
  7. -----------------|---------------|-----------------|-----------|
  8. 83886097221674.87|448588755196.12|20494100000000.00|42587778.47|

复制
2018 年全球 GDP 约为 83.9 万亿美元。聚合函数自动忽略 NULL 值,因此统计数据中不包含缺失的记录。
汇总得到的是数据的整体情况。虽然我们知道 GDP 最高值为 20 万亿美元,但不知道是哪个国家/地区;因此还需要针对个体进行分析。

数据排行榜

大家都说中国是世界上人口最多的国家,让我们来用数据验证一下:

  1. -- OracleSQL Server 以及 PostgreSQL 实现
  2. SELECT country_name, year, population
  3. FROM gdp_data WHERE year = 2018 AND population IS NOT NULL ORDER BY population DESC OFFSET 0 ROWS FETCH FIRST 10 ROWS ONLY;


复制
该查询返回了 2018 年度人口数量排名前 10 的国家/地区,我们在第 7 篇中学习了 FETCH 和 OFFSET 子句。MySQL 数据库中可以使用 LIMIT 10 实现相同的功能,大家可以自行尝试一下。
image.png
从数据可以看出中国的人口数量仍然最多,同时印度的人口数量已经非常接近中国。
再来看一下 2018 年度 GDP 的排名信息。除了数据之外,我们还增加了一个柱状图:

  1. -- Oracle 实现
  2. SELECT country_name, year, gdp, RPAD('█', gdp/250000000000, '█') AS "柱状图" FROM gdp_data WHERE year = 2018 AND gdp IS NOT NULL ORDER BY gdp DESC OFFSET 0 ROWS FETCH FIRST 10 ROWS ONLY;
  3. -- MySQL 实现
  4. SELECT country_name, year, gdp, rpad('█', gdp/250000000000, '█') AS "柱状图" FROM gdp_data WHERE year = 2018 AND gdp IS NOT NULL ORDER BY gdp DESC LIMIT 10;

复制
RPAD(str, length, pad_str) 是 Oracle 中一个函数,使用 pad_str 填充字符串 str,直到长度为 length。MySQL 和 PostgreSQL 也支持 RPAD 函数,SQL Server 可以使用 REPLICATE(str, count) 函数。
该查询的结果如下:
image.png
图形能够更加直观地感受数据之间的差异。虽然中国的人口数量最多,但是 GDP 和美国之间还存在一些差距。
GDP 反应的是一个国家/地区的生产总值,而每个国家/地区的人口数量不同;因此,我们还需要分析人均和占比数据。

人均、占比以及趋势分析

以下语句计算 2018 年每个国家/地区的人均 GDP 数据:

  1. SELECT country_name AS "国家/地区",
  2. year AS "年度",
  3. ROUND(gdp/population, 1) AS "人均 GDP"
  4. FROM gdp_data
  5. WHERE year = 2018
  6. AND population IS NOT NULL
  7. AND gdp IS NOT NULL
  8. ORDER BY ROUND(gdp/population, 1) DESC;

复制
该查询的结果如下(显示部分内容):
image.png
卢森堡的人均 GDP 最高,达到了 11.4 万美元;中国澳门特别行政区排在第 2 名。
接下来统计每个国家/地区在全球所占的比例。在前面我们已经得到了全球人口数量(7567243296)和 GDP 总量(83886097221674.87)。以下查询计算 2018 年各个国家/地区的人口和 GDP 占比:

  1. SELECT country_name,
  2. ROUND(population/7567243296, 5) * 100 AS "人口占比(%)",
  3. ROUND(gdp/83886097221674.87, 5) * 100 AS "GDP 占比(%)"
  4. FROM gdp_data
  5. WHERE year = 2018
  6. AND (population IS NOT NULL OR gdp IS NOT NULL) ORDER BY population DESC;

查询的结果中排除了人口数据和 GDP 都缺失的国家/地区。
image.png
最后分析一下 2018 年各个国家/地区的 GDP 增长率:

  1. SELECT country_name AS "国家/地区",
  2. SUM(CASE WHEN year = 2017 THEN gdp ELSE 0 END) AS "2017年GDP",
  3. SUM(CASE WHEN year = 2018 THEN gdp ELSE 0 END) AS "2018年GDP",
  4. (SUM(CASE WHEN year = 2018 THEN gdp ELSE 0 END)
  5. - SUM(CASE WHEN year = 2017 THEN gdp ELSE 0 END))/SUM(CASE WHEN year = 2017 THEN gdp ELSE 0 END) * 100 AS "2018 增长率(%)"
  6. FROM gdp_data WHERE year IN (2017, 2018) AND gdp IS NOT NULL GROUP BY country_name ORDER BY 4 DESC;

查询中使用了 CASE 表达式和 SUM 函数将行转换为列,然后使用 2018 年的 GDP 和 2017 年的 GDP 进行比较,计算 2018 年度 GDP 的增长率。
image.png
GDP 增长率高的基本都是经济体量比较小的国家/地区。

小结

本篇我们分析了世界银行公布的全球 GDP 和人口数据,回顾了使用 SQL 进行数据分析和统计的一些方法,同时也作为基础篇的一个总结。大家可以使用这个数据集进行更多的分析,来巩固已经学习到的知识。说说你通过分析有哪些新的发现?
练习题:编写 SQL 查询计算 2018 年度各个国家/地区的人口增长率。