鱼C论坛

 找回密码
 立即注册
查看: 1948|回复: 0

[见证历程] sql练习及理解_2

[复制链接]
发表于 2020-12-6 11:15:41 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 junkaiw 于 2020-12-7 10:29 编辑


                               
登录/注册后可看大图

                               
登录/注册后可看大图

目录
1. 行转列,列转行问题
2. 根据成绩判断是否及格问题
3. 部门表和员工表匹配展示问题



                               
登录/注册后可看大图

                               
登录/注册后可看大图


1. 行转列,列转行问题

  • 行转列

数据准备:
  1. create table course_01 (name varchar(30), course varchar(30), score int);

  2. insert into course_01 values ('jerry', 'math', 69);
  3. insert into course_01 values ('jerry', 'english', 89);
  4. insert into course_01 values ('cc', 'math', 49);
  5. insert into course_01 values ('cc', 'english', 99);
复制代码


示例数据展示:

                               
登录/注册后可看大图


期望效果:

                               
登录/注册后可看大图


方法一:case-when
  1. select name,
  2.                         sum(CASE course WHEN 'math' THEN score ELSE 0 END) as math,
  3.                         sum(CASE course WHEN 'english' THEN score ELSE 0 END) as english
  4. FROM course_01
  5. group by name
复制代码


重点知识整理
步骤理解:
1. 首先转换前和转换后name列是不会改变的,所以select 后面肯定需要有name
2. 其次如果不添加聚合函数sum,也不groupby,我们会得到一下结果:
  1. select name,
  2.                         (CASE course WHEN 'math' THEN score ELSE 0 END) as math,
  3.                         (case course when 'english' THEN score else 0 end) as english
  4. FROM course_01
复制代码


                               
登录/注册后可看大图

可以理解为每个学生的每门成绩我们都做出一个特定列来承载,如果不是所指定学科的成绩将置为0
3. 增加sum聚合函数是为了使得groupby后一个学生一门课程只能有一个成绩(不可能一会是0一会又不是)

方法二:if函数
  1. SELECT name,
  2.                         sum(if(course = 'math',score,0)) as math,
  3.                         sum(if(course = 'english', score,0))as english
  4. from course_01
  5. group by name
复制代码

整体思路其实是差不多的,只不过用if函数代替了case when


  • 列转行

数据准备:(将之前生成的行转列结果存入新表)
  1. create table course_02 as
  2. select name,
  3.                         sum(CASE course WHEN 'math' THEN score ELSE 0 END) as math,
  4.                         sum(case course when 'english' THEN score else 0 end) as english
  5. FROM course_01
  6. group by name
复制代码


示例数据展示:

                               
登录/注册后可看大图


期望效果:

                               
登录/注册后可看大图


  1. select name, 'math' as course, math as score from course_02
  2. union all
  3. select name, 'english' as course, english as score from course_02
复制代码


重点知识整理
1. 'math' as course 这个是增加了一个列,列名为course数据全部为‘math’
2. union all 和union 的区别:
union all 不会去重,union会去重
union会排序,union all只合并结果不排序
union all效率高



                               
登录/注册后可看大图

                               
登录/注册后可看大图

                               
登录/注册后可看大图


2. 根据成绩判断是否及格问题
数据准备:
  1. # 判断是否及格
  2. create table score_04(course varchar(10), score int);

  3. insert into score_04 VALUES('java', 70);
  4. insert into score_04 VALUES('sql', 90);
  5. insert into score_04 VALUES('python',30);
复制代码


示例数据展示:

                               
登录/注册后可看大图


期望效果:

                               
登录/注册后可看大图


方法一:case-when
  1. select course,score,
  2.         (case when score >=60 then 'pass' else 'fail' end ) as result
  3. from score_04
复制代码

重点知识整理
case when使用方法:
1. 多个字段的判断,case 后不指定字段,使用when来判断多个字段
case when ... then ... else ... end as列名
2. 单个字段的判断,case 接固定字段,按照值处理
case 字段 when .... then ... else ... end as列名
3. 多条件:
case
        when .... then...
        when .... then...
        else ..
        end as 列名

方法二:if函数
  1. select *, (if(score >=60, 'pass', 'fail')) as result
  2. from score_04
复制代码


说明:如果出现多条件,通常不用if处理



                               
登录/注册后可看大图

                               
登录/注册后可看大图

                               
登录/注册后可看大图



3. 部门表和员工表匹配展示问题
有两张表分别记录了部门情况,和员工情况,现需要根据部门id将两表关联展示员工、所在部门的信息。
数据准备:
  1. # 员工表
  2. drop table if EXISTS staff;
  3. create table staff(dptid int, name varchar(12));

  4. insert into staff values(1,'张三');
  5. insert into staff values(1,'李四');
  6. insert into staff values(2,'王五');
  7. insert into staff values(3,'彭六');
  8. insert into staff values(4,'陈七');
复制代码


                               
登录/注册后可看大图


  1. # 部门表
  2. create table department(id int, department varchar(10));
  3. insert into department values(1,'设计');
  4. insert into department values(2,'市场');
  5. insert into department values(3,'售后');
复制代码


                               
登录/注册后可看大图


期望结果:

                               
登录/注册后可看大图


  1. select ROW_NUMBER()over()as id, a.dptid as dptID, ifnull(b.department,'无')as department,a.name
  2. from staff a
  3. left join department b
  4. on a.dptid = b.id
复制代码


重点知识整理
1. 由于一般公司内部部门相关固定,但是有可能有员工没有部门,所以使用左连接
2. 由于本身表中没有员工编号,所以使用row_number对每个员工进行编号(假设不存在重复数据)
如果存在重复数据:
  1. select ROW_NUMBER()over()as id, c.* from
  2.         (select DISTINCT a.dptid as dptID, ifnull(b.department,'无')as department,a.name
  3.         from staff a
  4.         left join department b
  5.         on a.dptid = b.id) as c
复制代码


distinct 必须放在查询语句最前,所以需要先进行去重,然后在添加序号。

3.对一些关于操作null的函数的总结

-- isnull(exper) 判断exper是否为空,是则返回1,否则返回0

-- ifnull(exper1,exper2)判断exper1是否为空,是则用exper2代替

-- nullif(exper1,exper2)如果expr1= expr2 成立,那么返回值为NULL,否则返回值为   expr1。


想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-20 01:21

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表