查看原文
其他

数据治理 | 普通社科人如何学习SQL?一篇文章给您说明白

企研数据 数据Seminar 2022-12-31

我们将在数据治理板块中推出一系列原创推文,帮助读者搭建一个完整的社科研究数据治理软硬件体系。该板块将涉及以下几个模块:

  1. 计算机基础知识

(1)社科研究软硬件体系搭建——虚拟化技术概述与实践

  1. 编程基础

(1)数据治理 | 带你学Python之 环境搭建与基础数据类型介绍篇

(2)数据治理 | 带你学Python之控制结构与函数

(3)数据治理 | 带你学Python之面向对象编程基础

(4)数据治理 | 还在用Excel做数据分析呢?SQL它不香吗

(5)本期内容:数据治理 | SQL还停留在增删查改?这些简单操作看一眼就懂

  1. 数据采集
  2. 数据存储

(1)安装篇 数据治理 | 遇到海量数据stata卡死怎么办?这一数据处理利器要掌握

(2)管理篇 数据治理 | 多人协同处理数据担心不安全?学会这一招,轻松管理你的数据团队

(3)数据导入数据治理 | “把大象装进冰箱的第二步”:海量微观数据如何“塞进”数据库?

  1. 数据清洗
  2. 数据实验室搭建

前言

这篇文章属于 SQL 编程语法基础系列内容,该系列包含两部分内容,本文属于第二部分 (第一部分内容请看数据治理 | 还在用Excel做数据分析呢?SQL它不香吗),该文章主要讲解SQL为主。

本文讲述了在MySQL数据库中,对于表的各种常见操作及增删改查,没有讲述内容还有很多如:触发器、事务、视图等。通过该部分的学习,我们就可以满足日常的分析需求。对于没有讲到的内容,读者们可以根据实际情况自行扩展。

Part1SQL语法规定和示例表

任何语言都有语法规范,SQL也不例外,下面是SQL语法的基本规范:

  1. 不区分大小写,但是建议关键字大写,表名、列名小写。
  2.  SQL语句可以单行或多行书写,以分号结尾。
  3.  可使用空格和缩进来增强语句的可读性。
  4. SQL的两种注释方法:
  • 单行注释:-- 注释内容
  • 多行注释:/* 注释内容 */

为了方便大家学习,我们先创建了一张示例表,下图是一张示例表(篇幅有限,仅列出前20行),表名称为<国民经济指标2017>,我们后续的操作都会根据这一张表来实现:

Part2SQL语法进阶

(一)查询基础

从表中选取数据需要使用SELECT语句,SELECT语句是SQL语句中使用最多的最基本的SQL语句。

基本的SELECT语法:SELECT <列名> FROM <表名>

该SELECT语句包含了SELECT和FROM两个子句,子句是SQL语句的组成要素,是以SELECT或者FROM作为起始的短语。

SELECT子句中列举了希望从表中查询出的列名称,而FROM子句则指定了选取数据的表名称。

接下来我们根据 <国民经济指标2017> 这张表,来介绍数据查询的各种方法,因为文章的篇幅有限,我们在查询结果中,只展示前5行数据

1. 查询单列和多列

我们在查询数据的过程中,一般情况下并不会查询所有数据,而是针对部分数据进行查询,所以我们可以根据如下几条语句来查询部分列:

-- 查找 <国民经济指标2017>表中城市列的数据
select 城市 from 国民经济指标2017;

执行结果:

城市     |
- - - - +
杭州市   |
宁波市   |
温州市   |
嘉兴市   |
湖州市   |
-- 查找 <国民经济指标2017> 表中指定三列的数据,不同列需要用 , 隔开
select 城市, 指标名称, 指标取值 from 国民经济指标2017;

执行结果:

城市     | 指标名称     |  指标取值  |
- - - - + - - - - - - + - - - - - + 
杭州市   | 年末常住人口  | 946.8     |
宁波市   | 年末常住人口  | 800.5     |
温州市   | 年末常住人口  | 921.5     | 
嘉兴市   | 年末常住人口  | 465.6     |
湖州市   | 年末常住人口  | 299.5     |
-- * 表示所有 及查询表中所有的列
select * from 国民经济指标2017;

执行结果:

城市     | 指标名称       | 指标取值   | 指标单位   |
- - - - + - - - - - - - + - - - - - + - - - - - + 
杭州市   | 年末常住人口    |   946.8   | 万人       |
宁波市   | 年末常住人口    |   800.5   | 万人       |
温州市   | 年末常住人口    |   921.5   | 万人       |
嘉兴市   | 年末常住人口    |   465.6   | 万人       |
湖州市   | 年末常住人口    |   299.5   | 万人       |

2. 为列设定别名

我们也可以自定义列的名称,SQL语句可以使用AS关键字为列设定别名:

select 城市 as 'city', 指标名称 as 'variable'
from 国民经济指标2017;

执行结果:

city    |  variable       |
- - - - + - - - - - - - - +
杭州市   | 年末常住人口      |
宁波市   | 年末常住人口      |
温州市   | 年末常住人口      |
嘉兴市   | 年末常住人口      |
湖州市   | 年末常住人口      |

3. 从结果中删除重复行

有些情况下,我们需要对执行后的结果进行过滤,例如我们想要知道<国民经济指标2017>表中有哪些不同的指标,可以使用 distinct 关键词进行过滤:

select distinct 指标名称 from 国民经济指标2017;

执行结果:

指标名称       |
- - - - - - - +
年末常住人口    |
生产总值       |
第一产业       |
第二产业       |
第三产业       |

4. 根据where语句来选择记录

前面的列子都是将表中的数据全部取出来,但实际使用过程中,并不是每次都要选取全部的数据。

SELECT语句通过WHERE子句来指定查询的条件,即查询满足WHERE子句条件的数据,例如我们只想查询<指标名称>为<生产总值>的数据,可以这样写:

select * 
from 国民经济指标2017 
where 指标名称 = '生产总值';

执行结果:

城市     | 指标名称   | 指标取值   | 指标单位  |
- - - - + - - - - - + - - - - - + - - - - + 
杭州市   | 生产总值   | 12603.36  | 亿元     |
宁波市   | 生产总值   | 9842.06   | 亿元     |
温州市   | 生产总值   | 5411.59   | 亿元     |
嘉兴市   | 生产总值   | 4380.52   | 亿元     |
湖州市   | 生产总值   | 2476.13   | 亿元     |

(二)常用的运算符

1. 算数运算符

SQL语句中可以使用数学的运算符来对查询的结果进行算数运算,下表是主要的SQL主要的运算符:

运算符
含义
+
加法运算
-
减法运算
*
乘法运算
/除法运算

例如我们需要将指标取值的数据 × 10000,可以这么写:

select 城市, 
       指标名称, 
       指标取值 as '指标取值(万人)',
       指标取值 * 10000 as '指标取值(人)'
from 国民经济指标2017 
where 指标名称 = '年末常住人口';

执行结果:

城市     | 指标名称     | 指标取值(万人)  | 指标取值(人)  |
- - - - + - - - - - - + - - - - - - - + - - - - - - +
杭州市   | 年末常住人口  |   946.8       | 9468000.0   |
宁波市   | 年末常住人口  |   800.5       | 8005000.0   |
温州市   | 年末常住人口  |   921.5       | 9215000.0   |
嘉兴市   | 年末常住人口  |   465.6       | 4656000.0   |
湖州市   | 年末常住人口  |   299.5       | 2995000.0   |

注意:所有包含NULL的计算,结果都是NULL。

2. 比较运算符

我们在前面利用WHERE子句来选择记录的时候,就用到了比较运算符。常用的比较运算符有以下几种:

运算符

含义
=
等于
<>
不等于
>
大于
>=
大于等于
<
小于
<=
小于等于

比较运算符不能够与NULL值进行比较,因此,想要选取NULL的记录时,SQL提供了专门用来判断是否为 NULL 的 IS NULL 运算符:

-- 查询表中指标取值为NULL的数据
select *
from 国民经济指标2017 
where 指标取值 is null;

执行结果:

城市     | 指标名称     | 指标取值   | 指标单位    |
- - - - + - - - - - - + - - - - - + - - - - - +
丽水市   | 年末常住人口  |           | 万人       |
舟山市   | 生产总值     |           | 亿元        |
宁波市   | 第一产业     |           | 亿元        |
丽水市   | 第三产业     |           | 亿元        |
杭州市   | 出口总额     |           | 亿美元      |

3. 逻辑运算符

到目前为止,我们看到的每一条SQL语句中都只有一个查询条件,但是在实际使用当中,往往都是同时指定多个查询条件对数据进行查询的,逻辑运算符主要有:NOT、AND 和 OR。

NOT表示取反,NOT运算符不能单独使用,必须和其他查询条件组合起来使用。

例如利用NOT来选取表中<指标取值>不为NULL的语句可以这么写:

-- 获取指标取值不为 NULL的数据
select *
from 国民经济指标2017 
where 指标取值 is not null;

执行结果:

城市     | 指标名称     | 指标取值   | 指标单位    |
- - - - + - - - - - - + - - - - - + - - - - - +
杭州市   | 年末常住人口  | 946.8     | 万人       |
宁波市   | 年末常住人口  | 800.5     | 万人       |
温州市   | 年末常住人口  | 921.5     | 万人       |
嘉兴市   | 年末常住人口  | 465.6     | 万人       |
湖州市   | 年末常住人口  | 299.5     | 万人       |

AND运算符在其两侧的条件都成立时整个条件才算成立。

例如我们想要查询年末常住人口的指标取值大于500的数据,可以利用AND来查:

select *
from 国民经济指标2017 
where 指标名称 = '年末常住人口' and 指标取值 > 500;

执行结果:

城市     | 指标名称       | 指标取值   | 指标单位  |
- - - - + - - - - - - - + - - - - - + - - - - +
杭州市   | 年末常住人口    | 946.8     | 万人     |
宁波市   | 年末常住人口    | 800.5     | 万人     |
温州市   | 年末常住人口    | 921.5     | 万人     | 
绍兴市   | 年末常住人口    | 501.0     | 万人     |
金华市   | 年末常住人口    | 556.4     | 万人     |

OR运算符在其两侧的条件中有一个成立使整个查询条件都成立。

例如我们想要查询 年末常住人口和生产总值 这两个指标,我们可以使用OR来查:

select *
from 国民经济指标2017 
where 指标名称 = '年末常住人口' or 指标名称 = '生产总值';

执行结果(这边截取了部分段数据):

城市     | 指标名称     | 指标取值   | 指标单位   |
- - - - + - - - - - - + - - - - - + - - - - - +
杭州市   | 年末常住人口  | 946.8     | 万人       |
台州市   | 年末常住人口  | 611.8     | 万人       |
杭州市   | 生产总值     | 12603.36  | 亿元       |
宁波市   | 生产总值     | 9842.06   | 亿元       | 

TIPS: 如果我们需要查询的指标有很多,可以使用 IN 关键词:

select *
from 国民经济指标2017 
where 指标名称 in ('年末常住人口''生产总值''第一产业''第二产业');

执行结果(这边截取了部分段数据):

城市     | 指标名称     | 指标取值   | 指标单位    |
- - - - + - - - - - - + - - - - - + - - - - - +
杭州市   | 年末常住人口  | 946.8     | 万人       |
嘉兴市   | 生产总值     | 4380.52   | 亿元       |
丽水市   | 第一产业     | 99.44     | 亿元       |
湖州市   | 第二产业     | 1171.75   | 亿元       |
杭州市   | 出口总额     | 467.81    | 亿美元     |

(三)聚合与排序

1. 对表进行聚合查询

聚合函数就是通过SQL对数据进行某种操作或计算时需要使用的函数,所谓聚合,就是将多行汇总为一行,例如计算表中全部数据的行数时,可以使用COUNT函数。除此之外,SQL中还有很多其他用于汇总的函数,下表列出了5个常用的函数:

函数名称
含义
COUNT()
计算表中的记录数(行数)
SUM()
计算表中数值列中数据的合计值
AVG()
计算表中数值列中数据的平均值
MAX()
求出表中任意列中数据的最大值
MIN()
求出表中任意列中数据的最小值

我们想要知道表中一共有多少数据,可以使用COUNT函数来实现:

select count(*) as nums
from 国民经济指标2017;

执行结果:

nums  |
- - - +
187   |

我们想要知道所有城市的<出口总额>之和为多少,可以这么写:

select sum(指标取值) as 总和
from 国民经济指标2017
where 指标名称 = '出口总额';

执行结果:

总和     |
- - - - +
2826.77 |

AVG、MAX、MIN函数使用方法相同,读者们可以自行尝试。

2. 对表进行分组

目前为止,我们看到的聚合函数的使用方法,都是针对表中的所有数据进行的汇总处理,下面我们先把表分成几组,然后再进行汇总处理。

例如我们想要查询表中的指标个数,并统计每个指标的数据量为多少,可以使用如下语句:

select 指标名称, count(*) as nums
from 国民经济指标2017
group by 指标名称;

执行结果:

指标名称     | nums  |
- - - - - - + - - - +
年末常住人口  |  11   |
生产总值     |  11   |
第一产业     |  11   |

Tips:  GROUP BY 子句会将数值为NULL的数据也分为一组。

使用了GROUP BY 子句时,也可以使用WHERE子句。

假设我们想要查询杭州市的各个指标的数据量,可以这么写:

select 指标名称, count(*) as nums
from 国民经济指标2017
where 城市 = '杭州市'
group by 指标名称;

这样使用WHERE子句进行汇总处理时,会先根据WHERE子句指定的条件进行过滤,然后再进行汇总处理。

执行结果:

指标名称     | nums    |
- - - - - - + - - - - +
年末常住人口  |   1     |
生产总值     |   1     |
第一产业     |   1     |

目前SQL的子句还没有全部登场,SQL子句的顺序不能改变,也不能互相替换,已经出现的子句顺序如下所示:


SELECT → FROM → WHERE → GROUP BY 

3. 为聚合结果指定条件

使用前一节学过的GROUP BY子句,可以得到将表分组后的结果。如果我们想要选取特定的组,就要指定条件,说到指定条件,估计大家都会想到WHERE子句,但是,WHERE子句只能指定记录(行)的条件,而不能用来指定组的条件。因此,对集合指定条件就需要使用其他的子句了,此时便可以用HAVING子句。

例如我们想要了解各个指标名称分组后,包含数据的行数大于5行,可以这么写:

select 指标名称, count(*) as nums
from 国民经济指标2017
group by 指标名称
having count(*) > 5;

执行结果:

指标名称     | nums  |
- - - - - - + - - - + 
年末常住人口  |  11   |
生产总值     |  11   |
第一产业     |  11   |

HAVING子句需要写在GROUP BY 子句之后,使用HAVING子句时SELECT语句的顺序:

SELECT → FROM → WHERE → GROUP BY  → HAVING

4. 对查询结果进行排序

我们在查询的时候,通常数据是随机的,我们可以对查询的数据进行排序,这样方便我们使用,我们可以使用ORDER BY 子句来实现对数据进行排序:

select *
from 国民经济指标2017
where 指标名称 = '生产总值'
order by 指标取值;

执行结果:

城市   | 指标名称   | 指标取值  | 指标单位 |
- - - + - - - - - + - - - - + - - - - +
舟山市 | 生产总值   | 1219.78  | 亿元    |
丽水市 | 生产总值   | 1250.92  | 亿元    |
衢州市 | 生产总值   | 1331.27  | 亿元    |
湖州市 | 生产总值   | 2476.13  | 亿元    |
金华市 | 生产总值   | 3848.62  | 亿元    |

ORDER BY 子句默认是升序排列,我们想要降序排列可以使用DESC关键字:

select *
from 国民经济指标2017
where 指标名称 = '生产总值'
order by 指标取值 desc;

执行结果:

城市   | 指标名称 | 指标取值 | 指标单位  |
- - - + - - - - + - - - - + - - - - +
杭州市 | 生产总值 |12603.36 | 亿元     |
宁波市 | 生产总值 | 9842.06 | 亿元     |
温州市 | 生产总值 | 5411.59 | 亿元     |
绍兴市 | 生产总值 | 5078.37 | 亿元     |
台州市 | 生产总值 | 4388.22 | 亿元     |

Tips:

  • ORDER BY 子句可以指定多个列名排序,中间用逗号隔开,执行的时候会从左到右依次排序
  • 排序键中包含NULL值时,会在开头或者末尾进行汇总

子句的书写顺序:

SELECT  → FROM → WHERE → GROUP BY → HAVING → ORDER BY

(四)数据更新

1. 数据的插入

在数据插入之前,我们需要先创建表,创建表的CREATE TABLE语句格式为:

create table <表名>
(<列名1> <数据类型> <该列所需约束>,
 <列名2> <数据类型> <该列所需约束>,
 <列名3> <数据类型> <该列所需约束>,
          .
          .
          .
 <该表的约束1> <该表的约束2>,...);
例如我们仿造<国民经济指标2019>这张表的条件来创建一张表:
CREATE TABLE 国民经济指标2019 (
    城市 varchar(100) NULL,  -- varchar表示字符类型,NULL表示默认为空
    指标名称 varchar(100) NULL,
    指标取值 DOUBLE NULL,
    指标单位 varchar(100) NULL);

当表创建好之后,我们可以使用INSERT语句向表中插入数据,INSERT语句结构有两种:

-- 第一种: 插入一行数据(需要与表中列名数量一致)
insert into <表名> values(值1,值2,值3,值4);

-- 第二种: 插入一行中的部分列
insert into <表名> (列1,列2,列3,...) values (值1,值2,值3, ...);

假设我们后续获取到了一条信息,信息的内容为:义乌市的生产总值为2164.45亿元,我们将这条数据插入表中可以这么写:

insert into 国民经济指标2017 values('义乌市''生产总值', 2164.45, '亿元');
例如我们随后又获取到一条信息,信息的内容为:义乌市的第一产业值为213.12,这条信息没有单位,面对这种缺失部分数据的情况下,我们可以使用如下语句,进行插入:
insert into 国民经济指标2017(城市, 指标名称, 指标取值) values('义乌市''第一产业', 213.12);

2. 数据的删除

上一节我们学习了插入数据的方法,本节我们来学习如何删除数据。删除数据的方法大体可以分为以下两种。

  1. DROP TABLE 语句:可以将表从数据库中完全删除
  2. DELETE 语句:只是删除表中的全部数据,会留下表的结构

使用DROP TABLE语句会完全删除整张表,因此删除之后在想插入数据,需要使用CREATE TABLE语句重新建一张表,反之,使用DELETE删除行的的同时会保留数据表,之后还是可以通过INSERT语句再次向表中插入数据。

删除了的表是无法恢复的,所以在执行DROP TABLE语句之前务必仔细确认,例如我们想要删除<国民经济指标2017>这张表,可以使用DROP TABLE语句:
drop table 国民经济指标2017;
例如我们想要删除表中所有的数据,保留表容器可以使用DELETE语句:
delete from 国民经济指标2017;
通常在实际过程中,我们并不会删除表中所有的数据,而是删除部分数据,所以我们可以像查询数据一样,为表删除添加过滤条件,例如我们想要删除<国民经济指标2017>这张表中,城市为杭州市的数据,我们可以这样写:
delete from 国民经济指标2017 where 城市 = '杭州市';

注意:如果不添加“where”语句,整个表的数据都会被清空!

3. 数据的更新

使用INSERT语句向表中插入数据之后,有时却又想要再更改数据,例如某些指标的值发生错误,这时候并不需要把数据删除之后再重新插入,使用UPDATE语句就可以改变表中的数据了。

UPDATE语句语法:

update <表名> set <列名> = <表达式>;

注意:UPDATE与DELETE语法,需要通过WHERE子句来选择出指定的数据,否则UPDATE会更新整张表的数据

假设我们后续查阅数据的时候,发现<国民经济指标2017>表中杭州市年末常住人口实际为931.7万人,而在我们数据库中,指标取值为946.8万人,发现数据库中的数据是错误的,所以我们需要修改这一条数据就可以了:
update 国民经济指标2017 
set 指标取值 = 931.7 
where 城市 = '杭州市' AND 指标名称 = '年末常住人口';

Part3总结

本文主要讲解了一些简单的SQL语法,该语法只占数据库操作的一小部分,需要完全理解SQL还是略微有些难度的,读者们可以根据实际情况,自行扩展。




星标⭐我们不迷路!
想要文章及时到,文末“在看”少不了!

点击搜索你感兴趣的内容吧


往期推荐


数据可视化 | 数据可视化,看这一篇就够了

数据治理 | 数据分析的 5 种细分方法

统计计量 | 固定效应+聚类标准误是面板数据标配吗?

数据资源 | 社会科学数据资源汇总

统计计量 | 知乎热议:初学者如何学好计量经济学

软件应用 | Stata绘图:太美了!羊皮卷风格图形

数据治理 | 还在用Excel做数据分析呢?SQL它不香吗





数据Seminar




这里是大数据、分析技术与学术研究的三叉路口


文 | 金航凯


    欢迎扫描👇二维码添加关注    

点击下方“阅读全文”了解更多

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存