数据治理 | 普通社科人如何学习SQL?一篇文章给您说明白
我们将在数据治理板块中推出一系列原创推文,帮助读者搭建一个完整的社科研究数据治理软硬件体系。该板块将涉及以下几个模块:
计算机基础知识
编程基础 (1)数据治理 | 带你学Python之 环境搭建与基础数据类型介绍篇
(4)数据治理 | 还在用Excel做数据分析呢?SQL它不香吗
(5)本期内容:数据治理 | SQL还停留在增删查改?这些简单操作看一眼就懂
数据采集 数据存储 (1)安装篇 数据治理 | 遇到海量数据stata卡死怎么办?这一数据处理利器要掌握
(2)管理篇 数据治理 | 多人协同处理数据担心不安全?学会这一招,轻松管理你的数据团队
(3)数据导入数据治理 | “把大象装进冰箱的第二步”:海量微观数据如何“塞进”数据库?
数据清洗 数据实验室搭建
前言
这篇文章属于 SQL 编程语法基础系列内容,该系列包含两部分内容,本文属于第二部分 (第一部分内容请看数据治理 | 还在用Excel做数据分析呢?SQL它不香吗),该文章主要讲解SQL为主。
本文讲述了在MySQL数据库中,对于表的各种常见操作及增删改查,没有讲述内容还有很多如:触发器、事务、视图等。通过该部分的学习,我们就可以满足日常的分析需求。对于没有讲到的内容,读者们可以根据实际情况自行扩展。
Part1SQL语法规定和示例表
任何语言都有语法规范,SQL也不例外,下面是SQL语法的基本规范:
不区分大小写,但是建议关键字大写,表名、列名小写。 SQL语句可以单行或多行书写,以分号结尾。 可使用空格和缩进来增强语句的可读性。 SQL的两种注释方法:
单行注释:-- 注释内容 多行注释:/* 注释内容 */
为了方便大家学习,我们先创建了一张示例表,下图是一张示例表(篇幅有限,仅列出前20行),表名称为<国民经济指标2017>,我们后续的操作都会根据这一张表来实现:
Part2SQL语法进阶
(一)查询基础
基本的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>,...);
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, '亿元');
insert into 国民经济指标2017(城市, 指标名称, 指标取值) values('义乌市', '第一产业', 213.12);
2. 数据的删除
上一节我们学习了插入数据的方法,本节我们来学习如何删除数据。删除数据的方法大体可以分为以下两种。
DROP TABLE 语句:可以将表从数据库中完全删除 DELETE 语句:只是删除表中的全部数据,会留下表的结构
使用DROP TABLE
语句会完全删除整张表,因此删除之后在想插入数据,需要使用CREATE TABLE
语句重新建一张表,反之,使用DELETE
删除行的的同时会保留数据表,之后还是可以通过INSERT
语句再次向表中插入数据。
drop table 国民经济指标2017;
delete from 国民经济指标2017;
delete from 国民经济指标2017 where 城市 = '杭州市';
注意:如果不添加“where”语句,整个表的数据都会被清空!
3. 数据的更新
使用INSERT语句向表中插入数据之后,有时却又想要再更改数据,例如某些指标的值发生错误,这时候并不需要把数据删除之后再重新插入,使用UPDATE语句就可以改变表中的数据了。
UPDATE语句语法:
update <表名> set <列名> = <表达式>;
注意:UPDATE与DELETE语法,需要通过WHERE子句来选择出指定的数据,否则UPDATE会更新整张表的数据
update 国民经济指标2017
set 指标取值 = 931.7
where 城市 = '杭州市' AND 指标名称 = '年末常住人口';
Part3总结
本文主要讲解了一些简单的SQL语法,该语法只占数据库操作的一小部分,需要完全理解SQL还是略微有些难度的,读者们可以根据实际情况,自行扩展。
点击搜索你感兴趣的内容吧
往期推荐
数据可视化 | 数据可视化,看这一篇就够了
数据治理 | 数据分析的 5 种细分方法
统计计量 | 固定效应+聚类标准误是面板数据标配吗?
数据资源 | 社会科学数据资源汇总
统计计量 | 知乎热议:初学者如何学好计量经济学
软件应用 | Stata绘图:太美了!羊皮卷风格图形
数据治理 | 还在用Excel做数据分析呢?SQL它不香吗
数据Seminar
这里是大数据、分析技术与学术研究的三叉路口
文 | 金航凯
欢迎扫描👇二维码添加关注