第五周:MySQL

5.1 数据库基本概念

数据库是数据存储的集合,表示数据结构化的信息

列存储表中的信息,行存储表的明细

主键是表中的唯一标识,主键不具备业务意义

实际操作中,对表的主键不做强制性要求,但是建议设立

主键必须唯一

每行必须有一个主键,不可为空

主键的值不可被修改

主键值被删除后不可重用

表A的主键,可以作为表B的字段,此时不受约束

基本类型




mysql时刻相减 mysql 时间相减 为分_主键


两个坑:

数据库选择的是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


mysql时刻相减 mysql 时间相减 为分_主键_02


select city,count(1) from DataAnalyst
group by city


mysql时刻相减 mysql 时间相减 为分_mysql时刻相减_03


使用count函数,统计计数了每个城市拥有的职位数量。括号里面的1代表以第一列为计数标准。

DISTINCT

去处重复,返回唯一不同的值。

SELECT DISTINCT 列名称 FROM 表名称


select city,count(distinct positionId) from DataAnalyst
group by city


mysql时刻相减 mysql 时间相减 为分_ci_04


日常工作中,活跃用户数、文章UV,都是用distinct 计算获得,这是唯一标示符ID的重要作用。

当我们在group by 添加多个字段,它将以多维的形式进行数据聚合。


select city,workYear,count(distinct positionId) from DataAnalyst
group by city,workYear


mysql时刻相减 mysql 时间相减 为分_主键_05


IF


select if(industryField like '%电子商务%',1,0) from DataAnalyst


mysql时刻相减 mysql 时间相减 为分_ci_06


利用if判断出哪些是电商行业的数据分析师,哪些不是。if函数中间的字段代表为true时返回的值,不过因为包含重复数据,需要将其改成positionId。


select city,
       count(distinct positionId),
       count(distinct if(industryField like '%电子商务%',positionId,null)) 
from DataAnalyst
group by city


mysql时刻相减 mysql 时间相减 为分_主键_07


第一列数字是职位总数,第二列是电商领域的职位数,相除就是占比。记住,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


mysql时刻相减 mysql 时间相减 为分_mysql timediff 时间相减_08


也可以利用嵌套子查询。


mysql时刻相减 mysql 时间相减 为分_主键_09


将第一次查询获得的城市职位数的结果,看作一张新的表,利用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


mysql时刻相减 mysql 时间相减 为分_数据_10


统计结果升序排列,如果需要降序,则是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)


mysql时刻相减 mysql 时间相减 为分_ci_11


也可以改变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


mysql时刻相减 mysql 时间相减 为分_ci_12


使用left函数截取薪水的下限。


select left(salary,locate("k",salary)-1),salary from DataAnalyst


mysql时刻相减 mysql 时间相减 为分_数据_13


为了获得薪水的上限,要用substr函数,或者mid,两者等价。

substr(字符串,从哪里开始截,截取的长度)

薪水上限的开始位置是“-”位置往后推一位。截取长度是整个字符串减去“-”所在位置,刚好是后半段我们需要的内容,不过这个内容是包含“K”的,所以最后结果还得再减去1。


mysql时刻相减 mysql 时间相减 为分_ci_14


再然后计算不同城市不同工作年限的平均薪资。


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


mysql时刻相减 mysql 时间相减 为分_mysql timediff 时间相减_15


JOIN

join 用于根据两个或多个表中的列之间的关系,从这些表中查询数据。


mysql时刻相减 mysql 时间相减 为分_mysql timediff 时间相减_16


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


mysql时刻相减 mysql 时间相减 为分_主键_17


详见原作者文章:秦路: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默认关闭,因此用的时候需要打开。