一、连接查询方式
交叉连接: A (cross) join B = select * from A,B 。
其中join 方式 cross可以省略 ,即卡迪尔积。(没有on、where条件)
外连接:分为左连接、右连接、全连接。
左连接: A left (outer) join B on 以A表为基础,A表全部数据保留,如果B表有符合条件的记录就与A表连接。如果B表没有符合条件的记录,就用NULL与A表连接。
右连接: A right (outer) join B on 以B表为基础,B表全部数据保留,如果A表有符合条件的记录就与B表连接。如果A表没有符合条件的记录,就用NULL与B表连 接。
全连接: A full join B on 两表所有数据连接查询出来,A表有,
B表没有的数据(显示为null);同样B表有,A表没有的显示为null。
内连接:A (inner) join B on ,A表和B表的共有部分数据。
自然连接查询: A natural join B,自动将A表和B表相同名称的字段进行匹配(即只保留两个同名的字段下值相同的这条记录),然后去除重复字段(重复的字段保留一个),自连接自动完成,无法指定连接条件。
等值连接查询:当连接运算符为=时,称为等值连接。使用其他运算符称为非等值连接。
select * from A a , B b where a.aid = b.id
A (inner) join B on A.idid
非等值连接查询:连接两个表的条件为称为:连接条件或连接谓词
连接条件:
>、<
>=、<=
!=、<>
连接谓词:between and
select * from A a , B b where a.num >= b.num
select * from A a inner join B b on a.num >= b.num
自身连接:自身和自身连接。 A (cross) join A.
二、扩展-常用
图形 | 连接方式 | 说明 | SQL |
![]() | 内连接 | 共有部分 | select <select_list> from tablea a inner join tableb b on a.key = b.key; |
![]() | 左连接 | A表独有+共有部分 | select <select_list> from tablea a left join tableb b on a.key = b.key; |
![]() | 右连接 | B表独有+共有部分 | select <select_list> from tablea a right join tableb b on a.key = b.key; |
![]() | 全连接 | A的独有+共有部分+B的独有 | select <select_list> from tablea a full outer join tableb b on a.key = b.key; mysql不支持full outer join这种语法 |
![]() | A的独有 | select <select_list> from tablea a left join tableb b on a.key = b.key where b.key is null; | |
![]() | B的独有 | select <select_list> from tablea a right join tableb b on a.key = b.key where a.key is null; | |
![]() | A独有+B独有 | select <select_list> from tablea a full outer join tableb b on a.key = b.key where a.key is null or b.key is null; mysql不支持full outer join这种语法 |
二、举例
三张表:
current_stock 库存表
order_info 订单表
order_shop_details 订单详情表
CREATE TABLE `current_stock` (
`NID` int NOT NULL AUTO_INCREMENT,
`StoreID` int DEFAULT NULL,
`Number` decimal(10,0) DEFAULT '0' COMMENT '库存数',
`Money` decimal(14,4) DEFAULT '0.0000',
`Price` decimal(12,4) DEFAULT '0.0000',
`sku` varchar(50) DEFAULT '0',
PRIMARY KEY (`NID`) USING BTREE,
UNIQUE KEY `idx_storeId_sku` (`StoreID`,`sku`) USING BTREE,
KEY `Price` (`Price`) USING BTREE,
KEY `sku` (`sku`) USING BTREE,
KEY `StoreID` (`StoreID`) USING BTREE
) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='库存表';
CREATE TABLE `order_info` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键id(lp订单号5xxx)',
`platform_code` varchar(50) NOT NULL COMMENT '平台代码',
`shop_id` int NOT NULL COMMENT '店铺id',
`shop_name` varchar(50) NOT NULL COMMENT '店铺名',
`order_no` varchar(255) DEFAULT NULL COMMENT '平台店铺订单号',
`order_state` int DEFAULT '1' COMMENT '订单状态(0.异常订单 1.待派单 2.缺货订单 3.取消订单 4.已派单 5.未拣货 6.待拣货 7.缺货待包装 8.缺货订单中转 9.待包装 10.待发货 11.已发货 12.其他异常单)',
`sku_num` int DEFAULT '0' COMMENT '总SKU个数',
`multi_item` int DEFAULT '0' COMMENT '总购买数量',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=51200006 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='订单主表';
CREATE TABLE `order_shop_details` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键id',
`order_id` int NOT NULL COMMENT '订单lp编号',
`order_sort_id` varchar(11) DEFAULT NULL COMMENT '商品排序号',
`shop_sub_sku` varchar(100) DEFAULT NULL COMMENT '店铺sku(店子sku)',
`sku` varchar(100) DEFAULT NULL COMMENT '龙品商品sku(原子sku)',
`product_name` varchar(500) DEFAULT NULL COMMENT '商品名称',
`amt` decimal(11,4) DEFAULT NULL COMMENT '销售金额',
`qty` int DEFAULT NULL COMMENT '销售数量',
PRIMARY KEY (`id`) USING BTREE
)DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC COMMENT='订单详情信息表';
1、交叉连接: A (cross) join B 。其中cross可以省略 ,即卡迪尔积。(没有on条件)
A表有m条数据,B表有n条数据,则交叉连接结果集数据条数有m*n条数
SELECT * from order_info JOIN order_shop_details
三、深度解析-多表查询
3.1 什么是多表连接查询
在一个查询语句中显示多张表的数据,这也叫多表数据记录的连接查询。
在实现连接查询时,首先是将两个或两个以上的表按照某种关系连接起来(连接后形成一个新的关系表),然后再查询到所要求的的数据记录。
连接查询分为外连接查询和内连接查询。
3.2 表和表之间的关系
1. 并
并(union):将具有相同字段数目和字段类型的两张表关联到一起进行查询,
(1)union:去掉重复记录(两个表中每个字段的值都一样)
select 列 from 表1
union
select 列 from 表2
(2)union all:不会去掉重复的记录
select 列 from 表1
union all
select 列 from 表2
2. 笛卡尔积
笛卡尔积:将两张表的所有字段进行合并,两张表中的记录进行组合,比如第一个表中有3条记录,第二个表中有5条记录,两个表经过笛卡尔积操作后将一共会产生3*5=15 种数据记录。
select * from 表1,表2;
=select * from 表1 join 表2;
2. 连接查询
关系+连接条件
连接操作(JOIN):在表关系的笛卡尔积数据记录中,按照两个表中相应字段值的比较条件进行选择生成一个新的关系。其实就是将笛卡尔积后的数据记录进行筛选得到相应的数据,根据筛选方式不同,分为内连接(INNER JOIN),外连接 (OUTER JOIN),交叉连接(CROSS JOIN)。这些连接的基础都是笛卡尔积。
3.2 查询操作
1. 内连接查询(INNER JOIN)
内连接查询:保留关系中所有匹配的数据记录,舍弃不匹配的记录,注意,是只会保留符合匹配条件的记录,根据匹配条件分为:自然连接(natural join)、等值连接、不等连接。
(1). 自然连接
在笛卡尔积的数据记录中,首先自动根据关系中相同名称的字段进行记录匹配(即只保留两个同名的字段下值相同的这条记录),然后去除重复字段(重复的字段保留一个),使用关键字 NATURAL JOIN来进行自连接查询操作,自连接自动完成,无法指定连接条件。
换句话说,自然连接不设置连接条件,根据表中相同的字段进行记录匹配,去掉重复的字段。
SELECT * FROM 表1 NATURAL JOIN 表2;
示例:将r表和s表自然连接起来。
SELECT * FROM r NATURAL JOIN s;
(2). 等值连接
内连接查询中的等值连接,使用INNER JOIN…ON…的方式来实现,就是在关键字ON后面使用关系运算符“=”来指定等值条件,顾名思义,就是两个字段的值相等的条件.
等值连接要连接的表需有相同的字段,会匹配字段值相同的记录。
SELECT * FROM 表1 [AS] [表1别名]
INNER JOIN 表2 [AS] [表2别名] ON 表1别名.字段=表2别名.字段;
(3). 非等值连接
使用INNER JOIN…ON…的方式来实现,就是在关键字ON后面可以使用>、<、>=、<=、!=这些运算符来指定不等值的条件,所以叫不等连接。
示例:将R表和S表进行R.C<S.E的不等值连接。
SELECT * FROM r INNER JOIN s ON r.C<s.E;
2. 外连接查询(OUTER JOIN)
在表的笛卡尔集中,不仅保留所有匹配的数据记录,而且还会保留部分不匹配的数据记录,按照保留不匹配条件数据记录的来源可分为:左外连接(LEFT OUTER JOIN)、右外连接(RIGHT OUTER JOIN)、全外连接(FULL OUTER JOIN),外连接查询会返回操作表中至少一个表的所有数据记录。
(1). 左外连接(left join)
又称左连接,使用关键字 LEFT JOIN…ON…来实现,将笛卡尔积中满足条件的记录和左表中不满足条件的记录匹配出来。
(2). 右外连接(right join)
又称右连接,使用关键字 RIGHT JOIN…ON…来实现,将笛卡尔积中满足条件的记录和右表中不满足条件的记录匹配出来(保留右表中的所有记录,左表中没有匹配的记录显示为Null)。
(3). 全外连接(FULL JOIN)
SELECT * FROM r FULL JOIN s;
将笛卡尔积中满足条件的记录和左右表中不满足条件的记录都匹配出来。
(4). 等值连接
使用 【left、right、FULL】 JOIN…ON…的方式来实现,就是在关键字ON后面使用关系运算符“=”来指定等值条件,顾名思义,就是两个字段的值相等的条件.
-- 等值链接
SELECT
oi.`order_no` as aNo,
oi.`order_state`as aStatus,
oi.`sku_num` as aSkuSum,
oi.`multi_item` as aSum,
od.sku as osku,
od.qty as oSkuqty
from order_info oi LEFT JOIN order_shop_details od on oi.id=od.order_id
(5). 非等值连接
使用 【left、right、FULL】 JOIN…ON…的方式来实现,就是在关键字ON后面可以使用>、<、>=、<=、!=这些运算符来指定不等值的条件,所以叫不等连接。
SELECT
oi.`order_no` as aNo,
oi.`order_state`as aStatus,
oi.`sku_num` as aSkuSum,
oi.`multi_item` as aSum,
od.sku as osku,
od.qty as oSkuqty
from order_info oi LEFT JOIN order_shop_details od on oi.`sku_num` > od.qty
3. 交叉连接(CROSS JOIN)
交叉连接,实际上就是表笛卡尔积后的没有经过条件筛选后所有数据记录,不需要任何匹配条件。(与笛卡尔积结果相同)