SQL的多表连接查询(难点)

多表连接查询(难点)

连接查询 join

·连接查询用于根据表之间的关联关系(通常是外键)从多个表中获取数据

·as:起别名 可以省略用空格代替

·若两表有匹配行:行数取决于匹配的数量,可能为“1对1”(内连接找交集,行数不变)、“1对多”(比如左连接左边一行对应右边多行时,行数增加),极端情况下(如无有效关联条件)可能为两表行数的乘积(笛卡尔积)。

常见的连接类型包括:

1.内连接:[inner] join(查找显示两个表中相同字段的内容)

查询多张表(自连接一张表)中相关联的内容。

只返回多个表中匹配条件的记录,是最常用的连接方式。

只保留两表中同时满足关联条件的行

select 字段名

from 总表

inner join 表2 on 表1.某个相同字段=表2.某个相同字段

[inner join 表3 on 表3.某个相同字段=表1.某个相同字段

……];

只有在两个表中相同字段匹配的行才会出现在结果集中。

# 多表联查,通过inner join关联三个表:orders,users,products

# 关联条件是:

订单的用户 ID (o.user_id) 匹配用户表的 ID (u.id),

订单的商品 ID (o.product_id) 匹配商品表的 ID (p.id)

# 查询所有订单的用户和商品信息

select

o.id as 订单id,

u.username as 用户名,

p.name as 商品名称,

o.total_amount as 总金额

from orders o

inner join users u on o.user_id = u.id

inner join products p on o.product_id = p.id;

# 把所有订单的用户和商品信息全部排列组合一遍

# 同样关联三个表,查询字段更多

select

o.id as 订单id,

u.username as 用户名,

p.name as 商品名称,

o.quantity as 购买数量,

o.total_amount as 总金额,

o.create_time as 下单时间

from orders o

inner join:user u on o.users_id = u.id

inner join products p on o.product_id = p.id

where o.status = '已完成'

order by o.create_time desc;

# 笛卡尔查询(交叉连接cross join):将所有表中的所有内容都排列组合一次,不加关联条件时会产生。

·后面没写on+关联条件,产生 “笛卡尔积”(行数 = 表 A 行数 × 表 B 行数)

select

o.id as 订单id,

u.username as 用户名,

p.name as 商品名称,

o.quantity as 购买数量,

o.total_amount as 总金额,

o.create_time as 下单时间

from orders o

inner join users u

inner join products p;

2.左(外)连接:left join/left outer join

·返回左表中所有数据和右侧表中匹配条件的记录,右侧表无匹配则显示NULL

·以左侧的表为基准,获取所有数据,右表显示匹配到的数据,匹配不到的显示null(意思就是说,左连接会返回左表中的所有行,以及右表中与左表满足连接条件的行。如果右表中没有匹配的行,则对应列的值为NULL。)

select * from 主表 left join 从表 on 表1.字段 = 表2.字段;

# 查询所有用户及其订单情况(包括没有订单的用户)

select

    u.username as 用户名,

    count(o.id) as 订单数,

    ifnull(sum(o.total_amount), 0) as 总消费

from users u  

left join orders o on u.id = o.user_id

group by u.id, u.username;

3.右(外)连接:right join/right outer join

将右侧侧表中所有数据和左侧表中相关联数据查询出来,左侧表无关联则显示NULL

select * from 主表 right join 从表 on 表1.字段 = 表2.字段;

# 查询所有商品及其被购买情况(包括未被购买的商品)

select

p.name as 商品名称,

ifnull(sum(o.quantity),0) as 销售总量

from orders o

right join products p on o.product_id = p.id

group by p.id, p.name;

4.自连接:self join

将表与自身进行连接,通常用于处理表中存在层级关系

# 查询和张三同城市的用户

select u2.username, u2.city

from users u1

join users u2 on u1.city = u2.city

where u1.username = 张三 and u2.username !=张三;

联合查询union

合并时,两个表对应的列数和数据类型必须相同或者兼容。最终结果集的列数等于单个查询的列数,结果集的行数是多个查询结果的行数总和(union是去重后的总和,union all是不去重的总和)

1.union

合并结果集并去除重复的行

select 字段1, 字段2, ……

from 表1

where 条件

union

select 字段1, 字段2, ……

from 表2

where 条件;

2.union all

合并结果集但保留重复记录(效率比union高)

select 字段1, 字段2, ……

from 表1

where 条件

union all

select 字段1, 字段2, ……

from 表2

where 条件;

连接查询与联合查询的区别

特性

连接查询(join)

联合查询(union)

作用

横向关联多个表的数据

纵向合并多个查询的结果集

表关系

基于表间关联条件(如外键)

无关联要求,但列结构需一致

结果集结构

列数为各表列数之和

列数与各查询的列数相同

使用场景

需要同时展示多个表的关联信息

需要合并多个相似结构的查询结果

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值