第五周:MySQL
5.1 数据库基本概念
数据库是数据存储的集合,表示数据结构化的信息
列存储表中的信息,行存储表的明细
主键是表中的唯一标识,主键不具备业务意义
实际操作中,对表的主键不做强制性要求,但是建议设立
主键必须唯一
每行必须有一个主键,不可为空
主键的值不可被修改
主键值被删除后不可重用
表A的主键,可以作为表B的字段,此时不受约束
基本类型
两个坑:
数据库选择的是UTF8的时候,导入的数据也应是UTF8才可以,但Excel另存为UTF8形式的.csv在导入WorkBench时依然可能会报错,这是因为Excel另存为的UFT8具体为UTF-8-BOM编码格式,可使用NotePads等工具修改为UTF-8格式。
有时候会发现无论怎样WorkBench导入UTF-8数据时都会报错,这有可能是WorkBench的问题,建议换个版本试试。
5.2 MySQL语句
SQL 语句对大小写不敏感。SELECT 等效于 select。
SELECT
SELECT 列名称 FROM 表名称
SELECT 语句用于从表中选取数据。结果被存储在一个结果表中(称为结果集)。
WHERE
SELECT 列名称 FROM 表名称 WHERE 列 运算符 值
WHERE 子句用于规定选择的标准。如需有条件地从表中选取数据,可将 WHERE 子句添加到 SELECT 语句。
select * from DataAnalyst
where city = '上海'
我们也可以用 and 进行多条件判断。
select * from DataAnalyst
where city = '上海' and positionName = '数据分析师'
or 语句则是或的关系
select * from DataAnalyst
where city = '上海' or positionName = '数据分析师'
还可以用括号明确逻辑判断的优先级。
select * from DataAnalyst
where (city = '上海' and positionName = '数据分析师')
or (city = '北京' and positionName = '数据产品经理')
这条语句的含义是查找出上海的数据分析师或者是北京的产品经理。
当我们要查询多个条件,还可以使用 in 。
select * from DataAnalyst
where city in ('北京','上海','广州','深圳','南京')
当字段数据类型是数值时,也可以使用符号> 、>=、< 、<=、!= 进行逻辑判断,!= 指的是不等于,等价于 <> 。
select * from DataAnalyst
where companyId >= 10000
当我们需要取区间数值时,使用 between and
select * from DataAnalyst
where companyId between 10000 and 20000
between and 包括数值两端的边界,等同于
select * from DataAnalyst
where companyId >=10000 and companyId <= 20000
如果要模糊查找,能用like。
select * from DataAnalyst
where positionName like '%数据分析%'
语句的含义是在positionName列查找包含“数据分析”字段的数据,%代表的是通配符。
还有not,代表逻辑的逆转,常见not in、not like、not null等。
select * from DataAnalyst
where city not in ('北京','上海','广州','深圳','南京')
select * from DataAnalyst
where positionName not like '%数据分析%'
GROUP BY
GROUP BY 语句用于结合合计函数,根据一个或多个列对结果集进行分组。它是数据分析中常见的语法,目的是将数据按组/维度划分。类似于Excel中的数据透视表。
select * from DataAnalyst
group by city
select city,count(1) from DataAnalyst
group by city
使用count函数,统计计数了每个城市拥有的职位数量。括号里面的1代表以第一列为计数标准。
DISTINCT
去处重复,返回唯一不同的值。
SELECT DISTINCT 列名称 FROM 表名称
select city,count(distinct positionId) from DataAnalyst
group by city
日常工作中,活跃用户数、文章UV,都是用distinct 计算获得,这是唯一标示符ID的重要作用。
当我们在group by 添加多个字段,它将以多维的形式进行数据聚合。
select city,workYear,count(distinct positionId) from DataAnalyst
group by city,workYear
IF
select if(industryField like '%电子商务%',1,0) from DataAnalyst
利用if判断出哪些是电商行业的数据分析师,哪些不是。if函数中间的字段代表为true时返回的值,不过因为包含重复数据,需要将其改成positionId。
select city,
count(distinct positionId),
count(distinct if(industryField like '%电子商务%',positionId,null))
from DataAnalyst
group by city
第一列数字是职位总数,第二列是电商领域的职位数,相除就是占比。记住,count是不论0还是1都会纳入计数,所以第三个参数需要写成null,代表不是电商的职位就排除在计算之外。
HAVING
在 SQL 中增加 HAVING 子句原因是,WHERE 关键字无法与合计函数一起使用。
如果想找出各个城市,数据分析师岗位数量在500以上的城市有哪些,可以使用having语句,它对聚合后的数据结果进行过滤。
select city,count(distinct positionId) from DataAnalyst
group by city having count(distinct positionId) >= 500
也可以利用嵌套子查询。
将第一次查询获得的城市职位数的结果,看作一张新的表,利用as 将它命名为t1( table1 的简写),将职位数命名为一个新的字段counts。然后外面再套一层select 过滤出counts >=500。
ORDER BY
ORDER BY 语句用于根据指定的列对结果集进行排序。ORDER BY 语句默认按照升序对记录进行排序。如果希望按照降序对记录进行排序,可以使用 DESC 关键字。
select city,count(distinct positionId) as counts from DataAnalyst
group by city
order by counts
统计结果升序排列,如果需要降序,则是order by counts desc。
5.3 MySQL函数
时间
select now()
直接执行它,就能获得当前的系统时间,精确到秒。其实select不一定后面要跟from。
select date(now())
它代表的是获得当前日期,week函数获得当前第几周,month函数获得当前第几个月。其余还包括,quarter,year,day,hour,minute。
时间函数也包含各种参数,比如week,因为中西方计算第几天是不一样的,西方把周日算作一周中的第一天,而我们习惯周一。
select week(now(),0)
DATE_ADD() 给日期添加指定的时间间隔
DATE_SUB() 从日期减去指定的时间间隔
DATEDIFF() 返回两个日期之间的天数
select date_add(date(now()) ,interval 1 day)
也可以改变1为负数,达到减法的目的,也能更改day为week、year等,进行其他时间间隔的运算。如果是求两个时间的间隔,则是datediff(date1,date2)或者timediff(time1,time2)。
数据清洗
left、right、mid
select left(salary,1) from DataAnalyst
MySQL支持left、right、mid等函数,和Excel一样。
示例:通过salary计算数据分析师的工资
locate
用locate函数查找第一个k所在的位置。
select locate("k",salary),salary from DataAnalyst
使用left函数截取薪水的下限。
select left(salary,locate("k",salary)-1),salary from DataAnalyst
为了获得薪水的上限,要用substr函数,或者mid,两者等价。
substr(字符串,从哪里开始截,截取的长度)
薪水上限的开始位置是“-”位置往后推一位。截取长度是整个字符串减去“-”所在位置,刚好是后半段我们需要的内容,不过这个内容是包含“K”的,所以最后结果还得再减去1。
再然后计算不同城市不同工作年限的平均薪资。
select city,workYear,avg((bottomSalary+topSalary)/2) as avgSalary
from (select left(salary,locate("K",salary)-1) as bottomSalary,
substr(salary,locate("-",salary)+1,length(salary)- locate("-",salary)-1) as topSalary,
city,positionId,workYear
from DataAnalyst
where salary not like '%以上%') as t1
group by city,workYear
order by city,avgSalary
JOIN
join 用于根据两个或多个表中的列之间的关系,从这些表中查询数据。
select * from Students
join Address on Students.addressId = Address.id
join将Students和Address两表关联,关联需要一个或多个字段作为联接桥梁。
select * from Students as s
join Address as a on s.addressId = a.id
将表命名为一个缩略的别名,避免语句过于冗余。
Inner Join、Left Join、Right Join
详见原作者文章:秦路:SQL,从熟练到掌握
本地加载数据
load data local infile 'D:UserswangcDocumentsuser_info_utf.csv' into table data.userinfo fields terminated by '.';
如果出现ERROR 1148 (42000): The used command is not allowed with this MySQL version,这是因为服务器端,local_infile默认开启;客户端,local_infile默认关闭,因此用的时候需要打开。