case表达式用于多条件判断
case表达式相当于多条件判断函数,用于判断表中每一行数据是否满足某个条件
语法格式:
case 列名
when <条件判断表达式> then <结果表达式>
when <条件判断表达式> then <结果表达式>
when <条件判断表达式> then <结果表达式>
…
else <条件判断表达式>
end
由以上case表达式的语法可知,第一行when子句先判断完,输出then子句值,end结束,然后进行下一行判断,再次输出对应值。以此类推,直至表达式全部执行完毕。
case表达式的运作机制:第一条when语句会对整个SQL表格进行判断,判断结束后才会到第二个条件
(1) 多条件判断问题。(2)按区间统计问题。(3)行列互换问题。
面试题:

以60分为及格线,*标记出每一行的成绩是及格还是不及格。*
*select 学号,课程号,成绩,(*
*case*
*when 成绩 >= 60 then* *‘**及格**’*
*when 成绩 < 60 then* *‘**不及格**’*
*else null*
*end*
*) as 是否合格*
*from 学生成绩表;*

表4.5所示为“学生分数表”,表中记录有10个学生的分数情况,“学生编号”是唯一标识。请查询不及格(<60分)、及格(60~70分)、良好(71~85分)、优秀(86~100分)的学生各有多少人。
select 分数情况,count(distinct 学生编号) as 人数
from (
select 学号,课程号,成绩,(
case
when 成绩 < 60 then ‘不及格’
when 成绩>=60 and 成绩 <= 70 then ‘及格’
when 成绩 >70 and 成绩 <= 85 then ‘良好’
when 成绩 >=86 and 成绩 <=100 then ‘优秀’
else null
end
) as 分数情况
from 学生成绩表;
)
group by 分数情况;

“客户编码”是客户的唯一标识。分析订单数在0-2、3-5、5单以上的各有多少人


现需要查询运单号创建日期在5月、不同单量区间的客户分布。

行列转换



先按年来分组,如果没有max,那么结果是

有了之后就会对所有值取大赋给对应列

select 学号,
max(case 课程 where 课程=’语文’ then 成绩 else 0 end)
as 语文成绩,
max(case 课程 where 课程=’数学’ then 成绩 else 0 end)as数学成绩
from 成绩表
group by 学号;
当SQL语句中有太多子查询时,SQL语句的可读性就会变差
with … as 语句可以将SQL语句中的子查询定义为临时表,起到提高SQL语句可读性的作用
语法定义
with
临时表名称1 as 子查询语句1,
临时表名称2 as 子查询语句2,
….
多个临时表之间用,分隔,使用with.. as 语句定义完多个临时表之后不用;结束
*用with…as语句定义的临时表,后面必须直接跟使用该临时表的SQL语句,否则临时表将失效*
用with…as语句定义的临时表不需要删除,因为它在创建并使用后即释放,不会真实存放在数据库里。可以理解为,将一条SQL语句中的一部分片段封装起来,方便使用。因此,用with…as语句定义的临时表,属于后面直接使用该临时表的SQL语句的一部分,所以,在定义临时表后不能加语句结束符“;”
如果with…as语句定义的临时表名称与某个数据表或视图重名,则紧跟在该with…as语句后面的SQL语句使用的仍然是临时表,而没有紧跟在with…as语句后面的SQL语句使用的是数据表或视图, 面试题

with
a as (select distinct(顾客ID) from 销售订单表 where 产品=’ProductA’),
b as (select distinct(顾客ID) from 销售订单表 where 产品=’ProductB’),
c as (select distinct(顾客ID) from 销售订单表 where 产品=’ProductC’)
select count(distinct 顾客ID)
from 销售订单表
where 产品 in (select * from a)
and 产品 in (select * from b)
and 产品 not in (select * from c);
视图就是将SQL查询语句的结果视作视图
定义视图的SQL语法
*create view 视图名称 as*
*SQL查询语句;*
但是和临时表不同,视图是可以和真实表一样,对视图进行查询操作的
比如 :
select …
from 视图名称;
但是视图是一个虚拟表,因为视图不是真实存在于数据库所成的table,而视图本质上还是SQL语句,视图并不存放真实数据,视图运行结果表中的数据来自源表

视图起一个保证数据安全的作用

面试题
with…as语句和视图的区别
(1)with…as语句创建的是一个临时表,使用后即释放,不存放在数据库中,不需要删除;视图存储在数据库中,创建的是虚拟表,若要释放存储空间,则需要进行删除。(2)with…as语句不能使用语句结束符“;”;创建视图的语句是一条完整的SQL语句,需要使用语句结束符“;”。(3)with…as语句定义的临时表只能使用在紧跟其后的select语句中;视图则可以在不同的SQL语句中反复多次调用。(4)with…as语句的作用主要是提高SQL语句的易读性;视图除了可以提高SQL语句的易读性,也有保证数据安全的作用。
子查询就是在from子句中直接写SQL查询语句,就是将多个SQL查询语句嵌套在一起。
使用子查询就是把子查询的结果看做临时表
使用子查询时,一般需要用as关键字给子查询起个别名,方便在SQL其他地方使用。
关键字in 应用于子查询,in可以用于存在某个数值区间内,或者存在某个字段中
in 常使用于where子句中,表示查询某个范围内的数据。
in和子查询结合在一起的用法 是in (子查询)
all (子查询)和any(子查询)
all(子查询)和any(子查询)需要和比较运算符,包括“大于(>)”“小于(<)”“不等于(<>)”等一起使用
all 相当于逻辑上所有的与,表示当该数据满足所有结果的大小关系时才是返回值
any 相当于逻辑上所有的或,表示当该数据满足任意结果的大小关系时就是返回值
面试题

现在需要找出语文课中成绩排名第二的学生成绩。如果不存在第二名成绩的学生,那么查询应返回null。
select max(distinct 成绩)
from 成绩表
where 课程 = ‘语文’ and
成绩 < (select max(distinct 成绩)
from 成绩表
where 课程 = ‘语文’);

现在请查找既购买过ProductA产品又购买过ProductB产品,但没有购买ProductC产品的顾客人数。
select count(distinct 顾客ID)
from 销售订单表
where 顾客ID in ( select distinct 顾客ID from 销售订单表 where 产品= ‘ProductA’)
and 顾客ID in ( select distinct 顾客ID from 销售订单表 where 产品= ‘ProductB’)
and 顾客ID not in ( select distinct 顾客ID from 销售订单表 where 产品= ‘ProductC’)