Mysql练习(附答案)

  • 练习一 分组、过滤、连接
  • 练习二 增改表字段、改数据、计算
  • 练习三 IF条件过滤
  • 练习四 纵向连接,日期函数,子查询
  • 练习五 时间函数,子查询,多条件查询
  • 知识扩展

练习一 分组、过滤、连接

知识点:分组group by、过滤where…having、连接left/right…join…on

现有投资表和业务员表两张表,表结构及数据如下:



#创建invest表
create table invest(
created_at date,
user_id varchar(20),
invest_item varchar(100),
investamount decimal(38,10));
#给invest插入数据
insert into invest values
("2017/11/1","A123","CFH",100000),
("2017/12/5","A123","AX",450000),
("2017/12/11","A123","CH",700000),
("2017/12/6","B456","CFH",1500000),
("2017/12/26","B456","AX",800000),
("2018/1/6","C789","JUIN",300000);
#创建agent表
create table agent(
user_id varchar(20),
start_date date,
end_date date,
agent_id varchar(20));
#给agent插入数据
insert into agent values
("A123","2016/1/1","2017/12/4",10001),
("A123","2017/12/5","3001/12/31",10002),
("B456","2015/10/31","2016/12/15",10001),
("B456","2016/12/16","3001/12/31",10003),
("C789","2015/1/1","3001/12/31",10002);

开始做题:
1、计算2017年每笔投资均大于50万的用户

select user_id from invest  #从invest表中查询user_id
where year(created_at)=2017  #条件为created_at=2017
group by user_id   #对user_id分组
having min(investamount)>500000; #条件最小投资金额investamount小于50万

2、计算2017年仅投资过CFH和AX产品的用户

select user_id from invest
where year(created_at)=2017
group by user_id
having sum(invest_item="CFH")*sum(invest_item="AX") #同时满足两个条件
and count(distinct invest_item)=2; #容易入坑的地方:投资项目要等于2

3、计算归属于10002业务员的投资金额

SELECT b.agent_id,SUM(investamount) 投资金额
FROM invest a JOIN agent b on a.user_id=b.user_id  #连接两表
and a.created_at BETWEEN b.start_date and b.end_date #投资年份需要在业务员的工作时间范围内
WHERE b.agent_id='10002';  #条件:业务员编号为10002

练习二 增改表字段、改数据、计算

知识点:增加字段alter table 表名 add “字段1”(,“字段2”,“字段3”) 数据格式;加减计算;聚合函数sum()/avg()

1、以自己姓名创建一个数据库;

create database AK;

2、在此数据库下创建如下3表,数据类型,宽度,是否为空等,根据实际情况自己定义。
A. 雇员表(employee):
雇员编号(empid),姓名(name),性别(gender),职称(title),出生日期(birthday),
所在部门编号(depid);其中雇员编号为主键;
B. 部门表(department):
部门编号(depid),部门名称(depname);其中部门编号为主键。
C. 工资表(salary):
雇员编号(empid),基本工资(base_salary),职务工资(title_salary),扣除(deduction)。
其中雇员编号为主键。

create table employee(                      #创建employee雇员表empid varchar(10) primary key not null, #primary key主键,not null非空name varchar(10),gender varchar(10),title varchar(20),birthday date,depid varchar(10));create table department(                     #创建department部门表depid varchar(10) primary key not null,depname varchar(20));create table salary(                        #创建salary工资表empid varchar(10) primary key not null,base_salary decimal(8,2),title_salary decimal(8,2),deduction int);

3、修改表结构,在部门表中添加一个”部门简介”字段。
增加字段语法:alter table 表名 add “字段1”(,“字段2”,“字段3”) 数据格式;

alter table department add "部门简介" varchar(20);

4、插入以下数据

#在employee插入数据
insert into employee values
(1001,"张三","男","高级工程师","1975-1-1",111),
(1002,"李四","女","助工","1985-1-1",111),
(1003,"王五","男","工程师","1979-1-1",222),
(1004,"赵六","男","工程师","1979-1-1",222);insert into department values
(111,"生产部",null),
(222,"销售部",null),
(333,"人事部",null);insert into salary values
(1001,2200,1100,200),
(1002,1200,200,100),
(1003,1900,700,200),
(1004,1950,700,150);

5、将李四的职称改为“工程师”,并将她的基本工资改为5700元,职务工资为600

#分解步骤1:先更新数据语法update 表名 set 字段名=“新数据” (where 条件)
update employee set title="工程师" where empid=1002;
#分解步骤2:修改基本工资和职务工资
update salary set base_salary=5600,title_salary=600 where empid=1002;

6、查询出每个雇员的雇员编号,姓名,职称,所在部门,实发工资和应发工资。

分析思路:雇员编号在employee表,salary表都有(查找时需要在字段前加表名);姓名、职称仅在employee表;实发工资和应发工资需要在salary表进行计算:
实发工资=base_salary+title_salary-deduction
应发工资=base_salary+title_salary
查找的字段来自不同表,需要用到表连接,emlpoyee表于进行左连接

select employee.empid,name,title,depname,(base_salary+title_salary-deduction) as 实发工资,
(base_salary+title_salary) as 应发工资 from employee
left join salary on employee.empid=salary.empid  #根据empid字段进行emplyoee与salary左连接
left join department on department.depid=employee.depid;#根据depid字段进行emplyoee与department左连接

7、查询姓“张”且年龄小于40岁的员工的记录。
分解:查询姓张的员工记录、查询年龄小于40岁的员工记录,表中只有出生日期,需要通过year(),now()函数,获取年份

select * from employee where name like "张%" and year(now())-year(birthday)<40;

8、查询销售部所有雇员的雇员编号,姓名,职称,部门名称,实发工资
分析:本题是在第6题的基础上加了一个筛选部门的条件,因此只要复制修改原代码即可。(删除应发工资字段,最后面加一个where筛选条件)

select employee.empid,name,title,depname,(base_salary+title_salary-deduction) as 实发工资
from employee
left join salary on employee.empid=salary.empid
left join department on department.depid=employee.depid
where depname="销售部";

workbench代码及结果显示:

9、统计各类职称的人数。
分析:需要显示的字段为职称和人数,人数需要用count(*)函数。按职称分组group by。

select title,count(*) from employee group by title;

workbench代码及结果显示:

10、 统计各部门的部门名称,实发工资总和,平均工资。
分析:部门名称需要分组,实发工资总和需要用sum()函数,平均工资需要用avg()函数

select depname,sum(base_salary+title_salary-deduction)as 实发工资,
avg(base_salary+title_salary-deduction) as 平均工资  from employee
left join salary on employee.empid=salary.empid
left join department on department.depid=employee.depid group by depname;

workbench代码及结果显示:

练习三 IF条件过滤

知识点:条件过滤if(条件1,“符合条件1的输出”,if(条件2,“符合条件2的输出”,“不符合条件1和条件2的输出”))

要求:利用表1、表2、表3经过处理得到表4。


建表和插入数据可参考练习一和练习二完成。此处省略。如需要具体代码可以联系提供~
表名定义为:a、b、c
分析:字段LOAN_ON在a表和b表,ID_ON在a表和c表,ACTV_DT在a表,OD_DAYS在b表,LIM、OUTSTANDING在c表,其中LIM需进行一次求和,因为一个ID_ON存在多笔贷款信用记录(c表)
TYPE为计算字段:OD_DAY<0,TYPE为current;0<OD_DAY<=89,TYPE为middle;其他,chago
(用2次IF()函数)

select a.LOAN_NO,a.ID_NO,ACTV_DT,OD_DAYS,if(OD_DAYS=0,'CURRENT',IF(OD_DAYS>=90,'CHRGO','MIDDLE')) as TYPE,sum(LIM),OUTSTANDING from a left join b on a.LOAN_NO = b.LOAN_NOleft join c on a.ID_NO = c.ID_NOgroup by a.LOAN_NO;

workbench代码及结果显示:

练习四 纵向连接,日期函数,子查询

知识点:纵向连接union(如果不去重用union all),间隔日期函数date_add(curdate(),interval -7 days)

  1. 有以下表和字段:
    用户表:user,字段:user_id,name,create_time
    订单表:order,字段:order_id,user_id,create_time
    请写一条sql语句,做一个报表,包含如下字段:日期,新增用户数,当日订单数,当日下单用户数
    分析:
    a、两个表有相同字段名user_id,create_time。但是create_time含义不一样。user表中的create_time是注册日期,order表中的create_time是下单日期。所以直接用连接是是错误的。
    b、需要先生成一个日期表,包含user表和order表中的所有日期。用union
select * from
(select creat_time from user
union
select create_time from order)as a     #日期列表
left join user on a.create_time=user.create_time
left join order on a.create_time=order.create_time ;

c、计算和查询需要的字段(完整代码)

select a.create_time,
count(distinct user.user_id)新增用户数,  #需要统计非重复值
count(distinct order.order_id)当日订单数,
count(distinct order.user_id)当日下单用户数
from
(select creat_time from user
union
SELECT create_time from order)as a #日期列表
left join user on a.create_time=user.create_time
left join order on a.create_time=order.create_time
group by a.create_time;

2.有如下表和字段:
订单表:order,字段:order_id,user_id,city_id,create_time
请写一条sql语句,做一个报表,包含如下字段:城市id,最近7天内下过单的用户数,首次下单时间在最近7天的用户数
分析:
a、最近7天内需要用date_add日期偏移函数,语法date_add(开始日期,interval 天数 返回单位)
此例中需要在现在的日期curdate()减去7天,即date_add(curdate(),interval -7 days)。首次下单时间在最近7天的用户。首次下单时间:通过user_id 分组,找最小create_time就是首次下单时间。

select user_id from orders
group by user_id
having min(create_time)>= date_add(curdate(),interval -7 days);

b、那么首次下单时间在最近7天的用户数,需要用count(if)函数,如果首次下单时间在最近7天,则显示userid,否则显示null。

select  count(distinct if(user_id in (
select user_id from orders
group by user_id
having min(create_time)>= date_add(curdate(),interval -7 days)),userid,null))
首次下单时间在最近7天的用户数
from orders;

c、题目要求最终报表字段包含city_id

select city_id,count(distinct user_id) 最近7天内下过单的用户数,
count(distinct if(user_id in (select user_id
from orders
group by user_id
having min(create_time)>=date_add(curdate(),interval -7 day)),user_id,null))
首次下单时间在最近7天的用户数
from orders
where create_time>= date_add(curdate(),interval -7 day)
group by city_id;

workbench代码及结果显示:

练习五 时间函数,子查询,多条件查询

知识点:子查询常用in或and进行关联;
1.Order表字段:用户id,购买时间,订单id。
查询2017年购买过的用户在2018年每月的购买单量:
(1)2017年购买过的用户

select 用户ID from Order where year(购买时间)=2017

(2)在2018年需要用year=2018,每月购买需要用month(购买时间),故最终sql语句为:

select 用户ID,month(购买时间) 月份,count(订单ID) 订单数
from Order
where 用户ID in(select 用户ID from Order where year(购买时间)=2017) and year=2018
group by 用户ID,month(购买时间);

2.根据以下表,查找物流=2,服务=3,质量=5的评价id,表如下:

(1)看原表和需要查询的条件可知,需要新构建一个表,字段为用户ID,评价ID,物流评分,服务评分,质量评分。

SELECT 用户id,评价id,
sum(if(评价类别='物流',评价星级,null))物流,
sum(if(评价类别='服务',评价星级,null))服务,
sum(if(评价类别='质量',评价星级,null))质量
from 评价表
GROUP BY 用户id,评价id

(2)从新表a中再进行where查询,条件是"物流=2,服务=3,质量=5"(最终sql语句)

SELECT 评价ID FROM
(SELECT 用户id,评价id,
sum(if(评价类别='物流',评价星级,null))物流,
sum(if(评价类别='服务',评价星级,null))服务,
sum(if(评价类别='质量',评价星级,null))质量
from 评价表
GROUP BY 用户id,评价id) a
WHERE 物流=2 and 服务=3 and 质量=5;

知识扩展

1、查询的语法
select 字段列表
from 左表 left/right/inner join 右表 on 左表.连接字段=右表.连接字段
where 筛选条件
group by 分组字段
having 分组后条件
order by 排序字段
limit 限制输出行;
举例:
有4个表stu、co、te、sc表,sc和co表有相同字段c_id,co表和te表有过相同字段c_id。

#四个表做连接,选定字段。
select stu.*,co.c_id,c_name,score,te.* from stu left join sc on stu.s_id=sc.s_id
left join co on sc.c_id=co.c_id
left join te on co.t_id=te.t_id;

2、子查询
含义:子查询指一个查询语句嵌套在另一个查询语句内的查询,在select语句中先计算子查询,子查询结果作为外层另一个查询的过滤条件。子查询可以添加到select、update、delete语句中,而且可以进行多层嵌套。在子查询中常用的函数有any、all、in
举例:
a.查询比学生编号为02的学生的所有/任意一门课程成绩高的成绩信息

select *  from sc where score>all(select score from sc where s_id=02);
select *  from sc where score>any(select score from sc where s_id=02);

b.查询平均成绩大于等于60分的学生的成绩信息

select * from sc where s_id in (select s_id from sc group by s_id having avg(score)>=60);

c.查询选修了全部课程的学生信息:

select stu.* from stu left join sc on stu.s_id=sc.s_id
group by stu.s_id
having count(*)=(select count(*) from co);

3、date_add() 函数
含义:向日期添加指定的时间间隔。
语法:date_add(date,interval expr type)
举例:
a、得到当前时间增加1个小时的结果

select date_add(now(),interval 1 hour)

b、得到当前时间减少72个小时的结果

select date_add(now(),interval -72 hour)

数据分析师 Mysql练习题(附答案)相关推荐

  1. 计算机二级mysql大题_2016年计算机二级MySQL练习题及答案

    1[填空题]数据库系统的三级模式结构是指数据库系统是由________.________和________三级构成. 参考解析:模式 外模式 内模式 2[简答题]请简述PHP是什么类型的语言? 参考解 ...

  2. 阅读邮件回复邮件计算机操作题,《电子邮件》阅读练习题附答案

    <电子邮件>阅读练习题附答案 什么是电子邮件?它有哪些优点呢? 人们在电脑上写的信,由因特网上的一台主机传到另一台主机,最后送到收信人的.计算机上,这样发送和接收的信就叫"电子邮 ...

  3. 二级mysql大题_全国计算机等级考试二级MySQL练习题及答案

    下半年的计算机等级考试将在九月份举行,下面小编为大家带来了全国计算机等级考试二级MySQL练习题及答案,欢迎大家阅读! 全国计算机等级考试二级MySQL练习题及答案 一.选择题 1.在MySQL中,通 ...

  4. 中考计算机vb试题及答案,2017计算机二级VB练习题附答案

    2017计算机二级VB练习题附答案 引导语:全国计算机等级考试有二级VB语言程序设计这一考试项目.为了帮助大家准备计算机二级VB考试,以下是百分网小编分享给大家的2017计算机二级VB练习题附答案,欢 ...

  5. 计算机一级摸拟题练习,2017计算机一级MSOffice模拟练习题附答案

    2017计算机一级MSOffice模拟练习题附答案 引导语:2017年9月份的计算机考试快要来临了,你们都准备得怎么样了,以下是百分网小编分享给大家的2017计算机一级MSOffice模拟练习题附答案 ...

  6. 计算机进制转换专项训练,计算机各种进制转换练习题(附答案) (精选可编辑)...

    <计算机各种进制转换练习题(附答案) (精选可编辑)>由会员分享,可在线阅读,更多相关<计算机各种进制转换练习题(附答案) (精选可编辑)(5页珍藏版)>请在金锄头文库上搜索. ...

  7. 计算机一级考试做网络题,全国计算机等级考试一级考试练习题附答案

    全国计算机等级考试一级考试练习题附答案 为了使广大考生在备战计算机等级考试时,更快的掌握相应知识点,下面是小编搜索整理的全国计算机等级考试一级考试练习题附答案,供参考练习,预祝考生们考出自己理想的成绩 ...

  8. matlab sa(w),MATLAB平时练习题(附答案).pdf

    MATLAB平时练习题(附答案) 一.填空题 1.MATLAB 常用操作界面包括 .工作空间窗口 . . . 内存数组编辑器.M 文件编辑/调试器.帮助导航 /浏览器.图形窗口等. 2.MATLAB ...

  9. C 语言函数作业,c语言函数练习题附答案

    c语言函数练习题附答案 腕范匡秉蛹陀沿民鹅袱其噶厌裹拘娶欠总娃篆仟返赴邯凭诀腐病署库颧让输众琼聪楔了拧脆连捆点腥俘磅夯乓妙菩篙逆敷抄腾棉啼和试果砸临卸褂碰浙鳞码冗夜揉讨穆对抱寅秦轻个拯烧琼书釜和隐他痉 ...

最新文章

  1. 前端趋势榜:上周最有意思、又实用的 10 大 Web 项目 - 210821
  2. linux 共享内存_什么是物理/虚拟/共享内存——Linux内存管理小结一
  3. 斜面上的根骨骼运动以及刚体测试
  4. smartctl 输出详解
  5. ES6(三)——回调地狱和promise异步任务顺序执行(传参、错误处理)
  6. 博客版面设计~文章填充
  7. Keras学习---数据预处理篇
  8. Ubuntu20.04安装网易云音乐播放器
  9. 增强型绿植植被指数_植被指数--数据产品-国家青藏高原科学数据中心
  10. 【图像压缩】替换输入改善压缩+实现可变比特率
  11. 网站服务器会把手机拉黑吗,怎么知道对方手机把我拉黑了
  12. 学校计算机教室解说词词,小学各专用教室解说词.doc
  13. Docker操作步骤列表
  14. “天气之子”:GIS预测降雨
  15. vue中全局注册和局部注册
  16. xp电脑自动锁定计算机,WinXP系统如何设置电脑自动关机?
  17. 金蝉机器人_《金蝉脱壳2》残暴!机器人身份姓名首次曝光监狱更具压迫感
  18. 财务自由之路--笔记
  19. 动态社区网络前沿研究
  20. k8s对接smb/cifs存储

热门文章

  1. python爬虫实例之——多线程爬取小说
  2. javascript replace 替换全部
  3. 哪里可以查询所有网课的答案---【快捷查询】
  4. P2P-KAD(Kademlia)详解
  5. 2023系统分析师案例分析必备知识点
  6. iOS蓝牙开发(三):iOS中蓝牙模块OTA升级(YModem协议)
  7. 14、TheFatRat木马生成工具-创建后门或payload
  8. #、##、__VA_ARGS__和##__VA_ARGS__的作用
  9. Unity中文离线文档以及提升访问速度
  10. 181216 MacOs上如何将多页PDF文件合成打印在一张PDF表单上面