left join,right join,inner join
数据库中left join,right join,inner join的差异
具体详细说明
总的来说:
- JOIN: 有匹配的就返回。
- LEFT JOIN: 右表中没有,没关系,我左表的全部返回。
- RIGHT JOIN: 左表中没有就空着,右表的全部返回。
- FULL JOIN: 俩表中有一个就返回。
常用的来说,inner join,left join,其中inner join 经常省略了。
1、内连接(等值连接)
将两个表中存在连结关系的字段符合连接条件的记录形成记录集。只返回两个表中联结字段相等的行
Select A.name,B.name from A inner join B on A.id=B.id和
Select A.name,B.name from A,B where A.id=B.id结果是一样的(内连接的inner关键字可省略);
在表中存在至少一个匹配时,INNER JOIN 关键字返回行。
INNER JOIN 关键字语法
SELECT column_name(s)
FROM table_name1
INNER JOIN table_name2
ON table_name1.column_name=table_name2.column_name
2、外连接:分为左外连接和右外连接
left join左连接A、B表结果包括A的全部记录和符合条件的B的记录。返回包括左表中的所有记录和右表中联结字段相等的记录。
Select A.name,B.name from A Left Join B on A.id=B.id
其中LEFT JOIN 关键字会从左表 (table_name1) 那里返回所有的行,即使在右表 (table_name2) 中没有匹配的行。
LEFT JOIN 关键字语法
SELECT column_name(s)
FROM table_name1
LEFT JOIN table_name2
ON table_name1.column_name=table_name2.column_name
连接通常可以在select语句的from子句或where子句中建立,其语法格式为:
select colunm_name1,colunm_name2
from table_name1
left join table_name2
on table_name1.colunmname=table_name2.colunmname
其中join_table指出参与连接操作的表名,连接可以对同一个表操作,也可以对多表操作,对同一个表操作的连接称为自连接, join_type 为连接类型,可以是left join 或者right join 或者inner join 。
left join与where共同使用
select a.*,b.*
from table1 a
left join table2 b on b.X=a.X
where XXX
如上:一旦使用了left join,没有where条件时,左表table1会显示全部内容。使用了where,只有满足where条件的记录才会显示(左表显示部分或者全部不显示)
so。。。。
left join的困惑:一旦加上where条件,则显示的结果等于inner join
原因分析:
数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户;
where条件是在临时表生成好后,再对临时表进行过滤的条件;
因此:where 条件加上,已经没有left join的含义(必须返回左边表的记录)了,条件不为真的就全部过滤掉。
解决方案:
1、where过滤结果作为子查询,和主表left,如下:
select a.*,tmp.*from table1 aleft join(
select a.*,b.*
from table1 a
left join table2 b on b.X=a.X
where XXX
)tmp
很明显,子查询语句无论 left join、inner join都没啥区别了
2、查询条件放在on后面
select a.*,b.*
from table1 a
left join table2 b
on b.X=a.X and XXX
注意:where XXX去掉,改为链接条件on后面的 and XXX
分析:on条件是在生成临时表时使用的条件,它不管on中的条件是否为真,都会返回左边表中的记录。
结论:过滤条件放在:
where后面:是先连接然生成临时查询结果,然后再筛选。
on后面:先根据条件过滤筛选,再连 生成临时查询结果。
对于left join,不管on后面跟什么条件,左表的数据全部查出来,因此要想过滤需把条件放到where后面
对于inner join,满足on后面的条件表的数据才能查出,可以起到过滤作用。也可以把条件放到where后面。
on、where、having的区别
on、where、having这三个都可以加条件的子句中,on是最先执行,where次之,having最后。有时候如果这先后顺序不影响中间结果的话,那最终结果是相同的。
但因为on是先把不符合条件的记录过滤后才进行统计,它就可以减少中间运算要处理的数据,按理说应该速度是最快的。
在两个表联接时才用on的,所以在一个表的时候,就剩下where跟having比较了。在这单表查询统计的情况下,如果要过滤的条件没有涉及到要计算字段,那它们的结果是一样的。
如果要涉及到计算的字段,就表示在没计算之前,这个字段的值是不确定的,根据上篇写的工作流程,where的作用时间是在计算之前就完成的,而having就是在计算后才起作用的,所以在这种情况下,两者的结果会不同。
在多表联接查询时,on比where更早起作用。系统首先根据各个表之间的联接条件,把多个表合成一个临时表后,再由where进行过滤,然后再计算,计算完后再由having进行过滤。
由此可见,要想过滤条件起到正确的作用,首先要明白这个条件应该在什么时候起作用,然后再决定放在那里
标准的模板:
select * from (
select 表A.*,表B.*
from 表A left join 表B on 表A.x=表B.x )
where 表A.y<>表B.y or 表B.x is null;
left join是以A表的记录为基础的,A可以看成左表,B可以看成右表,left join是以左表为准的。
换句话说,左表(A)的记录将会全部表示出来,而右表(B)只会显示符合搜索条件的记录(例子中为: A.aID = B.bID)。B表记录不足的地方均为NULL。
right join右连接A、B表的结果和左连接B、A的结果是一样的,返回包括右表中的所有记录和左表中联结字段相等的记录。也就是说:
Select A.name,B.name from B Right Join A on B.id-A.id执行后的结果是一样的。
RIGHT JOIN 关键字会右表 (table_name2) 那里返回所有的行,即使在左表 (table_name1) 中没有匹配的行。
RIGHT JOIN 关键字语法
SELECT column_name(s)
FROM table_name1
RIGHT JOIN table_name2
ON table_name1.column_name=table_name2.column_name
一个误区:
想查询B表中的所有type为1的数据,A表中查出一些字段加入到B结果中。
比较下下面两句SQL
1.select * from A right join B on B.type=1 where A.id=B.aid;
2.select * from B left join A on A.id=B.aid where B.type=1 ;
我原先是按第一句写的,结果出来时,我感到很奇怪。为什么right join,不能把右边表里type为1的数据全部获取出来。
第一句,先执行on部分,查出了所有B的数据,然后和A进行右连接,最后根据条件A.id=B.aid,筛选数据,这样如果不满足A.id=B.aid的数据,将会从结果中去除,包括B的数据!
第二句,先执行on部分,查出A中所有满足A.id=B.aid的数据,再进行左连接,最后根据type=1做筛选。
可见,第二句sql才是正确的方法。
3,全连接Full join
只要其中某个表存在匹配,FULL JOIN 关键字就会返回行。
FULL JOIN 关键字语法
SELECT column_name(s)
FROM table_name1
FULL JOIN table_name2
ON table_name1.column_name=table_name2.column_name
下面列出了这几个可以使用的 JOIN 类型,以及它们之间的差异。
- JOIN: 如果表中有至少一个匹配,则返回行
- LEFT JOIN: 即使右表中没有匹配,也从左表返回所有的行
- RIGHT JOIN: 即使左表中没有匹配,也从右表返回所有的行
- FULL JOIN: 只要其中一个表中存在匹配,就返回行
多余:
三表联结查询
select username,psw,gname,tel from (t1 left join t2 on t1.t1_id=t2.t1_id) left join t3 on t1.t1_id=t3.t1_id
三个表信息:
tems:商品表,item_visit_stats:商品访问表,item_trade_stats:商品销售表
SELECT i.num_iid, i.title, i.price, SUM(iv.user_visits) AS uv,it.buyer_num,it.item_num,it.item_num*i.price AS turnover
FROM (
items AS i RIGHT JOIN item_visit_stats AS iv ON i.num_iid=iv.num_iid)
LEFT JOIN (
SELECT num_iid,SUM(buyer_num) AS buyer_num,SUM(item_num) AS item_num FROM item_trade_stats
WHERE seller_nick="XXXX" AND business_day BETWEEN '2017-08-14' AND '2017-08-15' GROUP BY num_iid)
AS it ON it.num_iid=iv.num_iid
WHERE i.nick="XXXX" AND iv.business_day BETWEEN '2017-08-14' AND '2017-08-15'
GROUP BY i.num_iid ORDER BY uv DESC
left join,right join,inner join的更多相关文章
- 1122MySQL性能优化之 Nested Loop Join和Block Nested-Loop Join(BNL)
转自http://blog.itpub.net/22664653/viewspace-1692317/ 一 介绍 相信许多开发/DBA在使用MySQL的过程中,对于MySQL处理多表关联的方式或者说 ...
- SQL JOIN\SQL INNER JOIN 关键字\SQL LEFT JOIN 关键字\SQL RIGHT JOIN 关键字\SQL FULL JOIN 关键字
SQL join 用于根据两个或多个表中的列之间的关系,从这些表中查询数据. Join 和 Key 有时为了得到完整的结果,我们需要从两个或更多的表中获取结果.我们就需要执行 join. 数据库中的表 ...
- hadoop 多表join:Map side join及Reduce side join范例
最近在准备抽取数据的工作.有一个id集合200多M,要从另一个500GB的数据集合中抽取出所有id集合中包含的数据集.id数据集合中每一个行就是一个id的字符串(Reduce side join要在每 ...
- SQL的inner join、left join、right join、full outer join、union、union all
主题: SQL的inner join.left join.right join.full outer join.union.union all的学习. Table A和Table B表如下所示: 表A ...
- 图解SQL的inner join(join)、left join、right join、full outer join、union、union all的区别
对于SQL的Join,在学习起来可能是比较乱的.我们知道,SQL的Join语法有很多inner的,有outer的,有left的,有时候,对于Select出来的结果集是什么样子有点不是很清楚.Codin ...
- Oracle 表的连接方式(1)-----Nested loop join和 Sort merge join
关系数据库技术的精髓就是通过关系表进行规范化的数据存储,并通过各种表连接技术和各种类型的索引技术来进行信息的检索和处理. 表的三种关联方式: nested loop:从A表抽一条记录,遍历B表查找匹配 ...
- Linq表连接大全(INNER JOIN、LEFT OUTER JOIN、RIGHT OUTER JOIN、FULL OUTER JOIN、CROSS JOIN)
我们知道在SQL中一共有五种JOIN操作:INNER JOIN.LEFT OUTER JOIN.RIGHT OUTER JOIN.FULL OUTER JOIN.CROSS JOIN 1>先创建 ...
- left join 和 left outer join 有什么区别?
left join 是left outer join的简写,left join默认是outer属性的.outer join则会返回每个满足第一个(顶端)输入与第二个(底端)输入的联接的行.它还返回任何 ...
- left join 和 left outer join 的区别
left join 和 left outer join 的区别 通俗的讲: A left join B 的连接的记录数与A表的记录数同 A right join ...
- Oracle中join left,join right,inner join,(+) 等
Oracle中join left,join right,inner join,(+) 等 博客分类: Oracle 建表create table TEST1create table TEST1( ...
随机推荐
- 让Android Support V4中的SwipeRefreshLayout支持上拉载入很多其它
前言 原来的Android SDK中并没有下拉刷新组件,可是这个组件确实绝大多数APP必备的一个部件.好在google在v4包中出了一个SwipeRefreshLayout.可是这个组件仅仅支持下拉刷 ...
- jQuery遮罩层插件
在网页上常常遇到须要等待非常久的操作,比方导出报表等.为了预防用户点击其它操作或者多次点击同个功能,须要用遮罩层把页面或者操作区盖住.防止用户进行下一步操作.同一时候能够提高界面友好度,让用户知道操作 ...
- 【SqlServer】【问题收集】阻止保存要求重新创建表的更改
1 概述 阻止保存要求重新创建表的更改,场景是这样的:假设数据库中有一张员工表EmployeeInfo,如下所示: 其中有个字段EmployeeBirthday,在设计表时,其类型误设为VARCH ...
- 转:java泛型
1.为什么需要泛型 转载请注明出处:http://blog.csdn.net/seu_calvin/article/details/52230032 泛型在Java中有很重要的地位,网上很多文章罗列各 ...
- eclipse ctrl shift t 失效的恢复方法
Window-->Perspective-->Customize Perspective 在弹出框选择: Action Set Avaliability ---将最右边的java Navi ...
- 【java提高】---ArrayList源码
ArrayList源码 一.定义 public class ArrayList<E> extends AbstractList<E> implements List<E& ...
- ios应用版本号设置规则
版本号的格式:v<主版本号>.<副版本号>.<发布号> 版本号的初始值:v1.0.0 管理规则: 主版本号(Major version) 1. 产品的主体构件进行 ...
- 【java】多线程同步死锁
package 多线程; class A{ public synchronized void say(B b){ System.out.println("A说:你把你的本给我,我把我的笔给你 ...
- iOS 蓝牙开发资料记录
一.蓝牙基础认识: 1.iOS蓝牙开发: iOS蓝牙开发:蓝牙连接和数据读写 iOS蓝牙后台运行 iOS关于app连接已配对设备的问题(ancs协议的锅) iOS蓝牙空中 ...
- scala写算法-快排
快排算法很经典,今天用scala的函数式思维来整理一下并实现: def qsort(list: List[Int]):List[Int]=list match { case Nil=>Nil c ...