SQL必知必会--中级篇(一)

前两篇文章已经回顾了最基础的部分,从这篇开始回顾一些进阶知识。

本篇包含知识点如图:

假设有两张表:student(sno,name,sex,age,class,addr) ,sno为主键

                        grade(id,sno,Math,Chinses,English),id为主键

以下sql语句,基于mysql数据库编写

一、组合查询(union)

union : 合并两个或多个select语句的结果集

使用规则:(1)必须由两条或两条以上的select语句组成,语句之间用关键字union分隔

              (2)每个select语句必须包含相同的列、表达式或函数

              (3)使用union组合查询时,只能使用 1条order by语句且必须位于最后一个select语句之后,它对返回的结果集进行排序

PS:union 自动去重,若想返回所有匹配的值(有重复的数据),应使用union all

select sno,Math,English
from student where sno = 2
union
select sno,Math,English
from student where Math > 80;      # 无重复值
select sno,Math,English
from student where sno in(2,4,6,8)
union all
select sno,Math,English
from student where Math > 70
order by Math DESC;                # 按照Math降序排列,返回所有满足条件的值 

二、别名(as)

as : 为表或者列指定别名

好处:(1)缩短sql语句,方便书写;(2)增强数据可读性 ;

PS:表的别名只在查询执行中使用

select sno as StudentNumber,name
from student;                         # 给sno设置别名StudentNumber
select s.sno,s.name,g.Math,g.English
from student as s,grade as g
where s.sno = g.sno;                  # 给两个表分别设置别名

三、联结表(join)

join : 基于表之间的共同字段,把两个或多个表结合起来

联结条件用特定的 on 子句给出

PS:处理联结非常耗费资源,联结的表越多,性能下降越厉害

(1)inner join : 内连接,只返回两个表能匹配的行;可以理解为数学中,两个集合的交集。

PS:内连接最常见,inner join 与 join相同 

select name,Math
from student inner join grade
on student.sno = grade.sno;      # 连接student和grade两个表,返回两个表都存在的对应数据

(2)left join : 左连接,返回左表(table 1)的所有行和右表(table 2)满足条件的行;若左表的行在右表中没有匹配的数据,则该行的右表数据用null表示。

select name,Math
from student left join grade
on student.sno = grade.sno;     # student为左表,grade为右表

(3)right join : 右连接,返回右表(table 2)的所有行和左表(table 1)满足条件的行;若右表的行在左表中没有匹配的数据,则该行的左表数据用null表示。

select name,Math
from student right join grade
on student.sno = grade.sno;     # student为左表,grade为右表

(4)full  outer join : 全连接,返回左表和右表的所有行,若没有对应匹配的,用null表示。

select name,Math
from student full outer join grade
on student.sno = grade.sno;         # student为左表,grade为右表

四、分组 (group by)

group by : 根据一个或多个列对结果集进行分组

PS:如果分组列中含有null数据,null将作为一个分组返回;若有多行null值,它们将分为一组;gruop by 应位于where子句后,order by 子句前

假设有两个表,user(uid,name,addr),id为主键

                       order(id,uid,product,number,price)

select u.uid,product,price
from user as u join order as o
on u.uid = o.uid
group by u.uid;                  # 查找每个用户购买的商品的价格
select u.uid,product,price,number
from user as u join order as o
on u.uid = o.uid
where number > 1
group by u.uid 
order by price DESC;           # 查找用户购买数量大于1的商品及价格,按照用户分组,按照价格降序排列

五、过滤分组(having)

having : 筛选分组后的数据

select uid,product,price,count(number) as total
from order
where price >10
group by uid
having count(number) > 2
order by uid;              # 查找每个用户购买的 价格大于10,商品数量大于2的商品,并按用户id排序

having 和 where的区别:where过滤行,having过滤分组;

PS:select子句顺序

子句 说明
select 要返回的列或表达式
from 从中检索数据的表
where 过滤行
group by 分组说明
having 过滤分组
order by 输出 顺序排序

猜你喜欢

转载自blog.csdn.net/zz_moon/article/details/80633803