多表联查--01---LEFT JOIN 实现多表联查
表的关系
- 一对一,一张表 有时候会为了性能而拆开(商品信息和商品备注信息–详情-很大)
- 一对多,必须两张表
- 多对一,反过来就是一对多,必须两张表
- 多对多,必须三张表,中间表,来维护它们之间的关系
笛卡尔积查询:
- 所谓笛卡尔积查询就是指,查询两张表,其中一张表有m条记录,另一张表有n条记录,查询的结果是m*n条。
笛卡尔积。
现在,我们有两个集合A和B。 A = {0,1} B = {2,3,4}
集合 A×B 和 B×A的结果集就可以分别表示为以下这种形式:
A×B = {(0,2),(1,2),(0,3),(1,3),(0,4),(1,4)};
B×A = {(2,0),(2,1),(3,0),(3,1),(4,0),(4,1)};
以上A×B和B×A的结果就可以叫做两个集合相乘的‘笛卡尔积’。
查询复杂度
例如: A表 n条记录,B表m条记录
- 表连接查询 select * from A left B on , 复杂度 n+m
- 相关子查询 select * from A IN (select * from B) , 复杂度 n*m
所以 mysql查询优化器可能对涉及子查询的查询语句进行重写, 转变为多表查询的操作,已降低查询的复杂度
案例:
tab1
tab2
SELECT * FROM tab1 ,tab2 ;
- 笛卡尔积=3*3=9
where 和 left join区别
数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户。
区别:
1. on条件是在生成临时表时使用的条件,它不管on中的条件是否为真,都会返回左边表中的记录。
2. where条件是在临时表生成好后,再对临时表进行过滤的条件。
这时已经没有left join的含义(必须返回左边表的记录)了,条件不为真的就全部过滤掉。
案例:
tab1
tab2
WHERE:
SELECT * FROM tab1 ,tab2 WHERE tab1.size = tab2.size ;
LEFT JOIN ON:
SELECT * FROM tab1 LEFT JOIN tab2 ON tab1.size = tab2.size;
SELECT * FROM tab1 LEFT JOIN tab2 ON tab1.size != tab2.size
解析:
1.数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表
相当于 SELECT * FROM tab1 ,tab2 ; ==> 中间的临时表
2.LEFT JOIN on条件是在生成临时表时使用的条件,
SELECT * FROM tab1 LEFT JOIN tab2 ON tab1.size != tab2.size;
其中tab1.size != tab2.size 是条件
3.不管LEFT JOIN on中的条件是否为真,都会返回左边表中的记录
SELECT * FROM tab1 LEFT JOIN tab2 ON tab1.size = tab2.size;
4. 我们再看where 多表联查:
SELECT * FROM tab1 , tab2 WHERE tab1.size = tab2.size;
where条件是在临时表生成好后,再对临时表进行过滤帅选
同理:
SELECT * FROM tab1 , tab2 WHERE tab1.size != tab2.size;
LEFT JOIN , RIGHT JOIN ,INNER JOIN对比
概念:
- left join(左联接) :把左边的全部查出来,右边有的则匹配,没有则为null
- right join(右联接) :返回包括右表中的所有记录,和左表中联结字段相等的记录
- inner join(等值连接): 只返回两个表中联结字段相等的行
案例:
tab1
tab2
SELECT * FROM tab1 ,tab2;
条件为tab1 .size = tab2.size;
SELECT * FROM tab1 , tab2 WHERE tab1.size = tab2.size;
SELECT * FROM tab1 LEFT JOIN tab2 ON tab1.size = tab2.size;
SELECT * FROM tab1 RIGHT JOIN tab2 ON tab1.size = tab2.size;
SELECT * FROM tab1 INNER JOIN tab2 ON tab1.size = tab2.size;
条件为tab1 .size != tab2.size
SELECT * FROM tab1 , tab2 WHERE tab1.size != tab2.size;
SELECT * FROM tab1 LEFT JOIN tab2 ON tab1.size != tab2.size;
SELECT * FROM tab1 RIGHT JOIN tab2 ON tab1.size != tab2.size
SELECT * FROM tab1INNER JOIN tab2 ON tab1.size != tab2.size
另: 只查询左表字段的的记录
SELECT tab1.id, tab1.salary, tab1.size
FROM tab1 LEFT JOIN tab2 ON tab1.size != tab2.size;
看上去像有重复记录,实际是没查全
中间临时表
加上 DISTINCT
SELECT DISTINCT tab1.id, tab1.salary, tab1.size
FROM tab1 LEFT JOIN tab2 ON tab1.size != tab2.size
解析:
因为on的条件tab1.size != tab2.size ,左表一条匹配到右边记录多条,所以单看左表会显示重复记录
如果要唯一 可以使用where 在on之后进行筛选,或者on后的条件 是一 一匹配.
题目:
需求:找出表tab1中 size和tab2中size不相等的记录
tab1
tab2
不能直接用left join on 去找
SELECT tab1.id,tab1.salary,tab1.size
FROM tab1 LEFT JOIN tab2 ON tab1.size != tab2.size;
因为: tab1.size != tab2.size ,左表一条匹配到右边记录多条,所以单看左表会显示重复记录
正确写法 1:
先找到相等的记录 ,在筛选
SELECT tab1.id,tab1.salary,tab1.size FROM tab1 WHERE tab1.id NOT IN (
SELECT tab1.id FROM tab1 INNER JOIN tab2 ON tab1.size = tab2.size );
或者
SELECT tab1.id,tab1.salary,tab1.size FROM tab1 WHERE tab1.id NOT IN (
SELECT tab1.id FROM tab1 , tab2 WHERE tab1.size = tab2.size );
注意:
上诉sql不能用left JOIN on 或者 right JOIN on
left 会默认返回所有 tab1.id
SELECT tab1.id FROM tab1 LEFT JOIN tab2 ON tab1.size = tab2.size
right 返回结果集 会有null 记录
- SELECT tab1.id FROM tab1 RIGHT JOIN tab2 ON tab1.size = tab2.size
INNER JOIN
SELECT * FROM tab1 INNER JOIN tab2 ON tab1.size = tab2.size
总结:
对于left join,不管on后面跟什么条件,左表的数据全部查出来,因此要想过滤需把条件放到where后面
对于inner join,满足on后面的条件表的数据才能查出,可以起到过滤作用。也可以把条件放到where后面。
正确写法 2:
not in 效率不高 可以考虑 not exists
SELECT id ,size,salary FROM tab1 AS a WHERE NOT EXISTS(
SELECT tab1.id FROM tab1 INNER JOIN tab2 =ON tab1.size =tab2.size
WHERE tab1.id= a.id )
正确写法 3:
SELECT tab1.id,tab1.salary,tab1.size FROM tab1 WHERE size NOT IN (
SELECT size FROM tab2 )
多表联查--01---LEFT JOIN 实现多表联查相关推荐
- 多表联查(多表连接)(join)
多表联查(多表连接)(join) 1. 分类 内连接.自然连接.外链接(左外连接.右外连接.全外连接(mysql不支持)) 2. 内连接 inner join(等值连接,制定对应的等值条件) SELE ...
- 使用left join实现多表联查
left join: 返回包括左表中的所有的记录和右表连接字段相等的记录 select * from A left join B on A.id = B.id 因为left join是以左表为主表,所 ...
- oracle 连多表查询语句,Oracle join多表查询
join(连接)是一个查询,它将来自两个或多个表.视图的数据组合在一起. 我通过一些示例来向大家介绍join的常用方法. 一.生成测试数据 1.创建超女基本信息历史表(T_GIRL_HIS) crea ...
- 1.19.5.4.流上的Join、常规Join、时间区间Join、时态表Join、基于处理时间的时态Join、时态表函数Join、用法
1.19.5.4.流上的Join 1.19.5.4.1.常规Join 1.19.5.4.2.时间区间Join 1.19.5.4.3.时态表Join 1.19.5.4.4.基于处理时间的时态Join 1 ...
- left join最多几张表_Spark中的join策略
背景 join是SQL中最常见的操作,写SQL最经常的场景就是几张表各种join,join操作也是各种操作中最耗时的操作之一. 作为一个Spark SQL Boy,有必要详细了解一下Spark的joi ...
- 【SQL】sql语句LEFT JOIN(拼接表)详解
1.语法 SELECT column_name(s) FROM table1 LEFT JOIN table2 ON table1.column_name=table2.column_name; 2. ...
- mysql right join实例_MySQL表LEFT JOIN左连接与RIGHT JOIN右连接的实例教程
LEFT JOIN 语法用法与实例MySQL LEFT JOIN 语法 SQL(MySQL) LEFT JOIN 会取得左表(table1)全部记录,即使右表(table2)并无对应匹配记录.LEFT ...
- pandas使用pd.concat横向合并多个dataframe实战:多个dataframe的横向表拼接(行对齐)、多个dataframe的横向表拼接(指定join参数、交集还是并集)
pandas使用pd.concat横向合并多个dataframe实战:多个dataframe的横向表拼接(行对齐).多个dataframe的横向表拼接(指定join参数.交集还是并集) 目录
- mysql+join+分库分表_MySQL分库分表篇
传统项⽬结构 数据库性能瓶颈: 1.数据库连接数有限 MySQL数据库默认100个连接.单机最⼤1500连接. 2.表数据量 1)表数量多,成百上千 2)单表数据,千万级别 3)索引,命中率问题,索引 ...
最新文章
- python 天气预报
- 调用支付宝接口android最新,Android 外接sdk之支付宝
- mysql 错误记录
- 常用公有云接入——亚马逊
- python利用matplotlib做饼图_python利用matplotlib库绘制饼图的方法示例
- 金陵科技学院计算机答辩,金陵科技学院优秀毕业论文答辩ppt模板
- jmeter.bat双击闪退问题
- Material Design基础
- python读取word文件内容_[python]读取word文档中的数据,整理成excel表
- Windows2008计算机设置,Windows Server 2008 R2 个人使用优化设置
- python打包的exe反编译_python打包exe反编译源码
- (附源码)springboot校园购物网站 毕业设计 041037
- 固态U盘能装linux么,用u盘在固态硬盘上安装linux 多重开启系统
- 服务器两个内存为何只显示4g_win10系统插入2个4G内存条却只显示4G的解决方法
- js获取剪切板文字图片方法
- iPhone又爆Wi-Fi漏洞 中招Wi-Fi就废了
- 十年再出发:阿里云智能战略加速的“四级火箭”...
- 水至清则无鱼,人至贱则无敌
- mdp文件-Chapter2-NVT.mdp
- 【CSS练习】IT修真院--练习3-简单界面