数据分析课程笔记 - 13 - MySQL(二)

大家好呀~ 今天是 Mysql 的第二课,主要学习数据的增删改查、筛选、分组、排序等操作,以及一些常用的函数。其中,筛选、分组、排序等操作是重点,也是难点,需要多多动手练习才能熟练掌握并灵活应用。

本节课主要
内容如下:

1、插入数据
2、更新表中数据
3、更新表结构
(1)增加列
(2)删除列
(3)拓展
4、删除
(1)删除某些行
(2)删除表
(3)删除数据库
(4)delete 与 drop 的对比
5、SQL基础查询
(1)建表和插入数据
(2)检索数据:select
(3)原表筛选条件:where
(4)数据分组:group by
(5)结果排序:order by
(6)MySQL查询语句基本格式
(7)MySQL语句解析顺序
6、SQL函数
(1)聚合函数
(2)时间日期函数
(3)字符串函数
(4)数学函数

一、插入数据

插入一行:

第一种写法(每一列都要有值):
INSERT INTO 表名
VALUES
(值1, 值2,...);

第二种写法(推荐,自己决定插入某些列的值):
INSERT INTO 表名
(字段1, 字段2, ...)
VALUES
(值1, 值2,...)

插入多行:
INSERT INTO 表名
(字段1, 字段2, ...)
VALUES
(值1, 值2,...),
(值1, 值2,...),
(值1, 值2,...),
(值1, 值2,...),
......

例如:

insert into student values(1,'zs');
insert into student (id,name) values  (2,'李四');
insert into student (id) values (3);

课堂练习:创建如下表格“order_2017”

练习

代码示例(自己练习完再看哦~):

# 创建表
create table order_2017(
    order_id VARCHAR(20),
    cust_id VARCHAR(20),
    date DATE,
    original_value FLOAT,
    discount FLOAT,
    items INT
);

# 添加数据
INSERT INTO order_2017 VALUES 
('0001','C1','2017-01-01',199.00,99.00,1),
('0002','C2','2017-01-01',30.70,0.00,3),
('0003','C3','2017-01-03',49.90,19.00,1),
('0004','C4','2017-02-19',125.00,0.00,5),
('0005','C2','2017-03-05',499.00,100.00,4),
('0006','C4','2017-11-11',273.50,23.50,11);

二、更新表中数据

语法结构:

UPDATE 表名   -- 要更新的表名
SET 字段=新值   -- 需要更新的字段和新值
WHERE 字段=旧值 -- 匹配需要更新的行

练习: 把订单ID为'0002'的订单中,日期改成'2017-04-01'

UPDATE order_2017
SET date = '2017-01-01'
WHERE order_id = '0002'

三、更新表结构

1、增加列

ALTER TABLE 表名
ADD 列名 数据类型
[约束条件] [FIRST | AFTER 已存在字段名];
-- 注:要是没有指定插入的位置,则默认插入到最后⼀列。

练习: 在 'order_2017' 表中,增加订单的实付金额 spend 列

ALTER TABLE order_2017
ADD `spend` FLOAT

2、删除列

ALTER TABLE 表名
DROP 列名;

练习: 在 'order_2017' 表中,删除订单的实付金额 spend 列

ALTER TABLE order_2017
DROP spend;

拓展

-- 修改表名
ALTER  TABLE 旧表名 RENAME  [TO] 新表名;

-- 修改字段的数据类型
ALTER  TABLE 表名 MODIFY 字段名 数据类型;

-- 修改字段名
ALTER  TABLE 表名 CHANGE 旧字段 新字段 新字段数据类型;

注:CHANGE也可以只修改数据类型,实现和MODIFY同样的效果, 即旧字段和新字段设置得⼀样。

-- 修改字段的排列位置
ALTER  TABLE 表名 MODIFY 字段1 数据类型 FIRST;
ALTER  TABLE 表名 MODIFY 字段1 数据类型 AFTER 字段2;

四、删除

1、删除某些行

语法结构:

delete from 表名  -- 从哪张表中删除
where 条件    -- 删除哪些⾏

练习: 在'order_2017'表中,删除订单ID为 '0002' 的订单

delete from order_2017
where order_id = '0002';

2、删除表

语法结构:

drop table 表名
或者
用工具手动删除

-- 删除多个没有被其他表关联的数据表。
DROP TABLE [IF EXISTS] 表1,表2,...表n;

2、删除数据库

语法结构:

drop database 数据库名;
或者
用工具手动删除

示例:删除名字为'xuexii'的数据库

DROP database xuexii;

4、delete 与 drop 的对比

delete 删除表中的内容,不删除表;(砍树枝、砍树叶)
drop 删除表或者数据库;(将树连根拔起)

五、SQL基础查询

1、建表和插入数据

-- 设定终端字符集
SET NAMES  GBK; -- Windows电脑需要设置终端字符集

-- 建 表
DROP TABLE IF EXISTS  `employee`;
CREATE  TABLE `employee` (
    `eno` int primary  key,
    `ename` varchar(20),
    `job` varchar(20),
    `mgno` int,
    `hiredate` date,
    `sal` double,
    `bonus` double,
    `deptno` int 17 
);

-- 插入数据
INSERT  INTO `employee` VALUES (1001, '钱多多', '总裁 ', NULL, '2009-11-17', 100000, 0, 10);
INSERT  INTO `employee` VALUES (1003, '张伟', '职员 ', 1021, '2010-12-17', 8000, 500, 20);
INSERT  INTO `employee` VALUES (1004, '王伟', '销售员 ', 1013, '2011-02-20', 6000, 1000, 30);
INSERT  INTO `employee` VALUES (1006, '王芳', '销售员 ', 1013, '2011-02-22', 6000, 500, 30);
INSERT INTO `employee` VALUES (1010, '李秀英', '经理 ', 1001, '2011-04-02', 50000, 500, 20);
INSERT INTO `employee` VALUES (1013, '李静', '经理 ', 1001, '2011-05-01', 35000, 500, 30);
INSERT INTO `employee` VALUES (1014, '赵丽', '经理 ', 1001, '2011-06-09', 20000, 500, 10);
INSERT INTO `employee` VALUES (1016, '⻢芯', '销售员 ', 1013, '2011-09-08', 6000, 500, 30);
INSERT INTO `employee` VALUES (1021, '⽜军', '分析师 ', 1010, '2011-12-03', 30000, 3000, 20);
INSERT INTO `employee` VALUES (1033, '孙刚', '职员 ', 1014, '2013-01-23', 6000, 0, 10);
INSERT INTO `employee` VALUES (1055, '张敏', '销售员 ', 1013, '2015-09-28', 5000, 500, 30);
INSERT INTO `employee` VALUES (1059, '刘洋', '助理 ', 1013, '2015-12-03', 5000, 1500, 30);
INSERT INTO `employee` VALUES (1087, '李强', '分析师 ', 1010, '2017-06-13', 20000, 500, 20);
INSERT INTO `employee` VALUES (1088, '韩爽', '职员 ', 1087, '2017-06-13', 8000, 1000, 20);

-- 建 表
DROP TABLE IF EXISTS `department`;
CREATE TABLE `department` (
    `deptno` int primary key,
    `dname` varchar(20),
    `location` varchar(20)
);

-- 插⼊数据
INSERT INTO `department` VALUES (10, '财务部', '北京');                  
INSERT INTO `department` VALUES (20, '运营部', '北京');                  
INSERT INTO `department` VALUES (30, '销售部', '全国各地');

2、检索数据:select

-- 1.查询所有的列
select *
from employee;

-- 2.查询单列:查询出员工表中员工编号eno列
select eno
from employee;

-- 3.查询多列:查询出员工表中员工编号、员工姓名列
select eno,ename
from employee;

-- 4.限制检索结果: limit
select *
from employee limit 3;

-- 5.去重检索:distinct

-- 5.1去重前
select job
from employee;

-- 5.2去重后
select distinct job
from employee;

-- 6.重命名查询出的列名: as
select distinct job as 职位类型
from employee;

3、原表筛选条件:where

-- 基本结构
select ...
from ...
where 条件;

# 判断条件
> < = <>(不等于) >= <=  BETWEEN AND OR NOT IN
like(%匹配任意长度的字符,包括零个字符  _:匹配任意⼀个字符)

# 使用ISNULL()来判断是否为NULL值,作为⼀个整体其简洁易懂,执行效率更快⼀些。

说明:NULL与任何值的直接比较都为NULL
①null <> null的返回结果是null,而不是false。
②null = null的返回结果是null,而不是true。
③null <> 1的返回结果是NULL,而不是true。

-- 1.检索出员工表中工资大于10000的员工信息
select *
from employee where sal>10000;

-- 2.查询员工表中工资⼤于10000并且拿到津贴的员工姓名select *
from employee
where sal>10000 and bonus>0;

-- 3.查询员工表中名字含有'伟'的员工姓名
select ename
from employee
where ename like '%伟%';

-- 练习:从员工表中筛选出部门编号为20或30、2013年~2015年期间入职、工资在5000以上(含5000)的员工信息

-- 查询计算字段:+ - * /
-- 创建的新字段可以使用别名:AS

基本格式:
select
    字段1+字段2 as '和', 
    字段1-字段2 as '差', 
    字段1*字段2 as '积', 
    字段1/字段2 as '商'
from 表 名

-- 4.查询员工表中每个员工的收入
income(income=sal+bonus)
select ename,sal+bonus as income
from employee;

-- 5.拼接字段
-- 错误写法
select (eno + ename) as "员工标识"
from employee;

-- 正确写法
select concat(eno,ename) as "员工标识"
from employee;

select concat(eno,"-",ename) as "员工标识" from employee;

4、数据分组:group by

-- 基本结构
SELECT 分组字段,聚合函数
FROM 表 名
group by 分组字段

-- 1.计算各级别员工的本月工资支出总和及津贴支出和
select job as 员工职级, 
    sum(sal) as '工资支出和', 
    sum(bonus) as "津贴支出和"
from employee 
group by job;

/* Having:分组筛选,对分组后的数据进行筛选

基本结构:
select 分组字段,聚合函数
from 表名
where 原表筛选条件
group by 分组字段
having 分组筛选条件

-- 2.找出工资支出总和大于50000的员工职级
select job,
sum(sal) as 工资支出和
from employee
group by job
having sum(sal) > 50000; 30

思考:having中的这个sum(sal)可以替换成 工资支出和 吗?
select job,
sum(sal) as 工资支出和
from employee
group by job
having 工资支出和 > 50000; 37

5、结果排序:order by

-- 计算每种职位的员工工资总支出与津贴总支出,只显示津贴总
支出超过1000的职位,并按照总工资从高到低进行排列。

select job as 职级名称,
sum(sal) as 职级总工资,
sum(bonus) as 职级总津贴
from employee
group by job
having sum(bonus)>1000
order by sum(sal) desc;
-- 注意:DESC表示降序排列,不写或者ASC是升序排列

6、MySQL查询语句基本格式

SELECT  查询字段,
DISTINCT <select_list> 去 重
FROM <left_table>   数据源
<join_type> JOIN <right_table> 连接表
ON <join_condition> 连接条件
WHERE <where_condition> 原表筛选条件
GROUP BY <group_by_list> 分组条件
HAVING <having_condition> 分组筛选条件
ORDER BY <order_by_condition> 排序条件
LIMIT <limit_number> 限制条件;

7、MySQL语句解析顺序

①from

②on

③join

④where

⑤group by

⑥having

⑦select

⑧distinct

⑨order by

⑩limit

六、SQL函数

1、聚合函数

1.  AVG():返回平均值
2.  MAX():返回最大值
3.  MIN():返回最小值
4.  SUM():返回总和
5.  COUNT():返回总个数

-- 1.查出员工表中的工资总⽀出、津贴总支出、平均工资
select sum(sal) 工资总支出, sum(bonus) 津贴总支出 , avg(sal) 平均工资
from employee;

-- 2.关于count的使⽤说明
select  count(*),
count(job),
count(distinct job) as 职级种类
from employee;

注意:①count(*) 计算表中总的行数,不管该列是否有值或者为空值
②count(字段) 计算指定列下的总行数,忽略空值的行
③不要使用count(列名)或count(常量)来替代count(*),count(*)是SQL92定义的标准统计行数的语法,跟数据库无关,跟NULL和非NULL无关。
④count(distinct 字段) 计算该列出NULL之外的不重复行数
⑤当某⼀列的值全是NULL时,count(col)的返回结果为0, 但sum(col)的返回结果为NULL,因此使⽤sum()时需要注意NPE 问题。

2、时间日期函数

时间格式:

DATETIME 举例:2000-12-01 12:18:30
DATE 举例:2000-12-01
YEAR 举例:2000

注:以下代码自己练习输入查看输出结果,这里就不展示啦~

⼀般的日期函数除了使用DATE类型的参数外,也可以使用DATETIME或者TIMESTAMP类型的参数,但会忽略这些值的时间部   分。相似的,以TIME类型值为参数的函数,可以接受TIMESTAMP 类型的参数,但会忽略日期部分,许多日期函数可以同时接受数字   和字符串类型的两种参数。

-- 1.select curdate(),current_date(),curdate()+0;
注:curdate()+0将日期值转换为数值型

-- 2.select curtime(),current_time(),curtime()+0;

-- 3.select
current_timestamp(),localtime(),now(),sysdate();
注:4个函数返回的结果是相同的,格式根据是字符串还是数字语境
中确定。

-- 4.select
unix_timestamp(),now(),unix_timestamp(now());

-- 5.select
from_unixtime(1596098121),from_unixtime('15960981
21');

注:from_unixtime()与unix_timestamp()互为反函数,是⼀对好基友!GMT为格林尼治时间!

-- 6.select utc_date(),utc_date()+0,utc_time();
注:UTC世界标准时间,并不是北京时间。

-- 7.select month('2020-07-30'),monthname('2020-
07-30');

-- 8.select dayname('2020-07-30'),dayofweek('2020-07-30');

-- 9.select weekday('2020-07-30 12:00:20'),weekday('2020-07-30');

10.日期格式化
date_format():格式化输出日期和时间值
time_format():格式化输出时间值

-- 练习:从员工表中查询每个员工的工龄
select hiredate as 入职时间, 
    datediff(current_date,hiredate) as '工龄(天)'
from employee;

3、字符串函数

同上,自己输入看结果哈~

-- 1.字符串长度
select char_length('test'),length('test'),char_length('数据分析'),length('数据分析');

注:char_length()返回值为字符串str所包含的字符个数;
length()返回值为字符串的字节长度,使用utf8编码字符集时,⼀个汉字是3个字节,⼀个数字或字符算1个字节。

-- 2.字符串拼接
select concat('My SQL','8.0'),concat('My',null,'SQL');

-- 3.字符串拼接
select concat_ws('-','1st','2nd','3rd'),concat_ws('*','1st',null,'3r
d');

-- 4.字符串截取
select left('football',3),right('basketball',4);

-- 5.剔除空格
select '( book )',concat('(',ltrim(' book'),')');

注:ltrim(s)返回字符串s,字符串左侧空格字符被删除。
rtrim(s)是删除右边的空格。trim(s)是删除两边的空格。

-- 6.剔除两端指定字符
select trim('ab' from 'abcabaaacbabbbb');
注:剔除字符串两端指定的字符

-- 7.字符串的替换
select
concat('(',space(6),')'),replace('xxx.mysql.com','x','w');
注:SPACE(n)返回⼀个由n个空格组成的字符串;
replace(s,s1,s2)返回字符串s2替代s中所有的s1。

-- 8.求子串substring/mid
select substring('breakfast',5)
col1,substring('breakfast',5,3) col2,substring('lunch',-3) as col3,substring('lunch',-5,3) as col4;
注:substring(s,n,len),从字符串s返回⼀个长度为len,起始位置为n的子串。n若为负值,则从右向左数n为起始位置。若len
小于1,则结果始终为空字符串。

注:substring(s,n,len),从字符串s返回⼀个长度为len,起始位置为n的子串。n若为负值,则从右向左数n为起始位置。若len
小于1,则结果始终为空字符串。

4、数学函数

-- 常见的数学函数
ABS(x):返回绝对值
PI():返回PI,7位有效数字
SQRT(x):返回非负数的平方根
MOD(x,y):返回余数
CEIL(x)/CEILING(x):返回不小于x的最小整数值,返回值转化为
⼀个BIGINT。
FLOOR():返回不大于x的最大整数值,返回值转化为⼀个BIGINT。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,755评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,369评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,799评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,910评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,096评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,159评论 3 411
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,917评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,360评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,673评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,814评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,509评论 4 334
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,156评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,882评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,123评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,641评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,728评论 2 351

推荐阅读更多精彩内容