-
2021-02-01 06:44:56
相信很多朋友在写sql的时候会用到 left join on,right join on, inner join on 这种连接方式,但是如果想在我们连接的表中去过滤某个条件该怎么做呢,是直接在 on 后面加 and 还是直接在where中加条件呢?之前自己遇到这种情况总是先去做尝试,对于这其中的原理不明白。通过网上搜索以及自己实践,把自己的见解以及网上搜到的一些结果写下来,以便以后回顾使用。
数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户。
left join on :
1. on条件是在生成临时表时使用的条件,它不管on中的条件是否为真,都会返回左边表中的记录。 on 后面跟and条件,先会在右边表中对and条件进行过滤,然后再跟左边主表进行关联。
2. where条件是在临时表生成好后,再对临时表进行过滤的条件。这时已经没有left join的含义(必须返回左边表的记录)了,条件不为真的就全部过滤掉。
示例:
表table1
id no
1 101
2 102
3 103
4 104
5 105
表table2
no name
101 a
103 b
104 c
SELECT * FROM table1 t1 LEFT JOIN table2 t2 ON (t1.no = t2.no AND t2.no='103')
查询结果如下:
t1.id t1.no t2.no t2.name
1 101 (null) (null)
2 102 (null) (null)
3 103 103 b
4 104 (null) (null)
5 105 (null) (null)
SELECT * FROM table1 t1 LEFT JOIN table2 t2 ON t1.no = t2.no WHERE t2.no='103'
查询结果如下:
t1.id t1.no t2.no t2.name
3 103 103 b
其实以上结果的关键原因就是left join,right join,full join的特殊性,不管on上的条件是否为真都会返回left或right表中的记录,full则具有left和right的特性的并集。
而inner jion没这个特殊性,则条件放在on中和where中,返回的结果集是相同的。
更多相关内容 -
laravel leftjoin on orOn的源码剖析
2020-09-17 16:00:20laravel leftjoin on orOn的源码剖析, leftjoin连接时需要对不止一个条件进行进行匹配,这时候就需要使用闭包方式leftjoin连接时需要对不止一个条件进行进行匹配,这时候就需要使用闭包方式
leftjoin('db', function ($join) {···});
文章目录
原生join orOn例子
原生sql例子如下:
SELECT * FROM `a` LEFT JOIN `b` ON `b`.`deleted_at` IS NULL AND ( `a`.`a` = `b`.`a` AND `a`.`b` = `b`.`b` AND `a`.`c` = `b`.`c` ) OR ( `a`.`a` = `b`.`a` AND `a`.`b` = `b`.`b` AND `a`.`d` = `b`.`d` )
想用model的方法实现join 的 orOn,百度谷歌过后没有找到合适的资料
官方文档的orOn资料如下:
https://laravel.com/docs/6.x/queries#joinsCross Join Clause
To perform a “cross join” use the crossJoin method with the name of the table you wish to cross join to. Cross joins generate a cartesian product between the first table and the joined table:
$users = DB::table('sizes') ->crossJoin('colors') ->get();
Advanced Join Clauses
You may also specify more advanced join clauses. To get started, pass a Closure as the second argument into the join method. The Closure will receive a JoinClause object which allows you to specify constraints on the join clause:
DB::table('users') ->join('contacts', function ($join) { $join->on('users.id', '=', 'contacts.user_id')->orOn(...); }) ->get();
源码剖析
这时候只能寻找源码了
先从
$join->on
开始文件地址:
vendor/laravel/framework/src/Illuminate/Database/Query/JoinClause.php
/** * AddHoneycombLog an "on" clause to the join. * * On clauses can be chained, e.g. * * $join->on('contacts.user_id', '=', 'users.id') * ->on('contacts.info_id', '=', 'info.id') * * will produce the following SQL: * * on `contacts`.`user_id` = `users`.`id` and `contacts`.`info_id` = `info`.`id` * * @param \Closure|string $first * @param string|null $operator * @param string|null $second * @param string $boolean * @return $this * * @throws \InvalidArgumentException */ public function on($first, $operator = null, $second = null, $boolean = 'and') { if ($first instanceof Closure) { return $this->whereNested($first, $boolean); } return $this->whereColumn($first, $operator, $second, $boolean); } /** * AddHoneycombLog an "or on" clause to the join. * * @param \Closure|string $first * @param string|null $operator * @param string|null $second * @return \Illuminate\Database\Query\JoinClause */ public function orOn($first, $operator = null, $second = null) { return $this->on($first, $operator, $second, 'or'); }
由上可见,join中的on 可以传递
$boolean = 'or'
的
使用on 传递boolean参数 === orOn方法单where条件
可以通过以下代码实现:
$info = DB::table('table_name') ->leftJoin('table_name2', function ($join) { $join->on('table_name.a', '=', 'table_name2.a') ->orOn('table_name.b', '=', 'table_name2.b'); })->get();
查看
whereColumn
方法文件地址:
/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php
/** * AddHoneycombLog a "where" clause comparing two columns to the query. * * @param string|array $first * @param string|null $operator * @param string|null $second * @param string|null $boolean * @return \Illuminate\Database\Query\Builder|static */ public function whereColumn($first, $operator = null, $second = null, $boolean = 'and') { // If the column is an array, we will assume it is an array of key-value pairs // and can add them each as a where clause. We will maintain the boolean we // received when the method was called and pass it into the nested where. if (is_array($first)) { return $this->addArrayOfWheres($first, $boolean, 'whereColumn'); } // If the given operator is not found in the list of valid operators we will // assume that the developer is just short-cutting the '=' operators and // we will set the operators to '=' and set the values appropriately. if ($this->invalidOperator($operator)) { [$second, $operator] = [$operator, '=']; } // Finally, we will add this where clause into this array of clauses that we // are building for the query. All of them will be compiled via a grammar // once the query is about to be executed and run against the database. $type = 'Column'; $this->wheres[] = compact( 'type', 'first', 'operator', 'second', 'boolean' ); return $this; }
由
is_array
可见,是可以传递数组的多where条件
可以通过以下代码实现:
$info = DB::table('table_name') ->leftJoin('table_name2', function ($join) { $join->on([ ['table_name.a', '=', 'table_name2.a'], ['table_name.b', '=', 'table_name2.b'], ['table_name.c', '=', 'table_name2.c'], ]) ->orOn([ ['table_name.a', '=', 'table_name2.a'], ['table_name.b', '=', 'table_name2.b'], ['table_name.d', '=', 'table_name2.d'], ]); })->get();
上述代码已用model的方式实现了原生sql
laravel leftjoin on orOn的源码剖析就到这了,希望文章可以帮忙解决你的难题,期待你的关注👍
-
left join on 后and 和 where 的区别
2020-12-20 13:02:54left join on 后and 和 where 的区别俩者放置相同条件,但是结果集不同,就是由于优先级不同,on的优先级高于where的。首先得明确俩个概念使用 left join 会返回左表中所有的数据,及时右表中没有匹配的行。俩个表...left join on 后and 和 where 的区别
俩者放置相同条件,但是结果集不同,就是由于优先级不同,on的优先级高于where的。
首先得明确俩个概念使用 left join 会返回左表中所有的数据,及时右表中没有匹配的行。
俩个表关联查询时,首先生成一张临时表,然后再将这张临时表返回。
俩者的区别and 是在生成临时表时候起作用的,不管条件是否成立,都会返回左表中的全部数据。
where 是在生成临时表之后起作用的,那么就会对临时表中的数据过滤。
案例
创建表1 teacher 和表2 student 如下图
SELECT * from teacher t LEFT JOIN student s ON t.id = s.teacher_id and s.`name` = '韩信';
SELECT * from teacher t LEFT JOIN student s ON t.id = s.teacher_id WHERE s.`name` = '韩信';
第一条语句结果集:
第二条语句结果集:
第一条语句执行的时候 (t.id = s.teacher_id and s.name = '韩信' )是一个整体 ,找到 student 表中符合的行于teacher 表中匹配 , 及时teacher 中有不符合的数据也会生成临时表返回。
第二条语句执行的时候 先执行了 (t.id = s.teacher_id) 生成临时表返回,然后where 条件过滤,所以存在丢失teacher 中的数据。
结论如果左标中的数据全部返回 left join 后要用 and。
where 会对左表中的数据过滤会丢失。
t.id = s.teacher_id and s.name = '韩信' )是一个整体,这样就很好理解俩者的区别。
-
left join on多条件深度理解
2022-04-28 14:17:31left join on多条件深度理解 核心:理解左连接的原理! 左连接不管怎么样,左表都是完整返回的 当只有一个条件a.id=b.id的时候: 左连接就是相当于左边一条数据,匹配右边表的所有行,满足on后面的第一个条件a.id=b...left join on多条件深度理解
核心:理解左连接的原理!
左连接不管怎么样,左表都是完整返回的
当只有一个条件a.id=b.id的时候:
左连接就是相当于左边一条数据,匹配右边表的所有行,满足on后面的第一个条件a.id=b.id的进行返回
当有两个条件的时候a.id=b.id and a.age>100(当第二个条件进行左表筛选时)
就是左边这张表只有a.age>100的行,才会参与右表的每行匹配(但是a.age<100的行也会返回,只不过age<100的行是不可能匹配到右表的,因为根本不参加匹配)
当有两个条件的时候a.id=b.id and b.monkey>100(第二个条件进行右表筛选)
就是左边这张表每一行,参与右表的monkey>100的每一行的匹配
实例
两个表里面有13能匹配上
普通左连接:
SELECT u.*,ul.* FROM `user` u left join user_like ul on u.id=ul.id
左连接多条件+第二个条件进行左边筛选
SELECT u.*,ul.* FROM `user` u left join user_like ul on u.id=ul.id and u.id<2
左连接多条件+第二个条件进行右表筛选
SELECT u.*,ul.* FROM `user` u left join user_like ul on u.id=ul.id and ul.monkey>150
-
SQL 中JOIN ON 的AND条件设置
2020-09-05 15:01:44关于在A LEFT JOIN B ON A.id =B.id 后面跟AND 条件的测试。 有如下的结构数据: 注意此LEFT ON 跟AND 限制A表的场景; dat a.sql 1.43KB 有如下的表结构 使用SQL进行查询: (1)SELECT * FROM `... -
left join inner join on 和where区别
2019-04-20 09:57:20在使用left join 时,on和where条件的区别: 1:on条件是在生成临时表时使用的条件,它不管on中的条件是否为真,都会返回左边表中的记录。 2:where条件是在临时表生成好后,再对临时表进行过滤的条件。这时已经... -
(四)sql多表连接查询join on的用法
2019-08-04 18:45:53(四)sql多表连接查询join on的用法 -
left join on and 和 left join on where的区别
2018-07-13 16:59:27一、left join on on条件是在生成临时表时使用的条件,它不管on中的条件是否为真,都会返回左边表中的记录。 二、left join on and (1)如果and语句是对左表进行过滤的,那么不管真假都不起任何作用。 (2... -
mysql语法 join on 表示什么
2021-03-14 21:14:53mysql语法 join on 表示什么 今天在写sql语句的时候遇到了join on 这个东西表示的是外连接还是内连接呢?想要验证其实并不难 查询出来的数据量 –129 SELECT count(1) FROM t_budget a left JOIN t_budget_item b on... -
left join on后面 加条件 与 where后面加条件的区别
2022-03-25 09:27:18left join on后面 加条件 与 where后面加条件的区别,数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户。 在使用left jion时,on和where条件的区别如下: 1、 on... -
SQL多字段JOIN(两个表JOIN ON多字段)
2021-01-12 14:02:20全网首发SQL多字段JOIN JOIN ON 多字段 HIVE多字段JOIN MySQL多字段JOIN 两个表JOIN ON多字段 JOIN ON 后面不是 等于号 -
关于SQL Server中left join on and 用法的介绍
2019-12-06 17:05:13一般情况下,SQL语句的执行顺序如下所示: (1)from (2)on (3)join (4)where ...从SQL语句执行顺序的这个角度,我们可以很好的理解left join on and的用法。 以SQL Server为例,先创建两个测... -
mysql where和 join on 哪个效率高
2021-01-18 22:18:24展开全部关于 “A LEFT JOIN B ON 条件636f707962616964757a686964616f31333363373666表达式” 的一点提醒ON 条件(“A LEFT JOIN B ON 条件表达式”中的ON)用来决定如何从 B 表中检索数据行,即使on中包含有A表中的... -
mysql join on多条件关联on大于小于
2020-11-19 15:16:43使用join关联表时on后面写多个条件 代码 SELECT * FROM lecture l INNER JOIN lecture_limit lt ON l.id = lt.lecture_id INNER JOIN student_class sc ON sc.CODE = lt.CODE OR floor( sc.CODE / 1000 ) ... -
关于Left Join On的使用
2020-05-12 11:48:02在进行公司项目超猿的CRMPC端后台会员列表页面开发时,初始为了省事方便,直接使用全表查询,由于该功能项设计了三个表的数据,全表查询导致了查询速度过于...Left Join俗称左连接,也就是吧left join左边的表的记录全 -
join on用法
2019-01-14 17:52:071.join on用法,返回两张表中相等的数据 select * from testa join testb on aid=bid 结果: 与join on 执行结果一致的是select * from testa where aid in(select bid from testb ) 也与select * from t... -
mysql left join on使用两个或多个字段关联查询
2021-10-28 10:13:40mysql left join on使用两个或多个字段关联查询解决查询如下 解决 left join on 通过两个或多个字段才可以关联到一条数据 ON concat( o.to_id, o.from_id )= concat( r.to_id, r.from_id ) 查询如下 SELECT o.id,r.... -
MySQL select join on 连表查询和自连接查询
2020-09-22 18:19:08JOIN ON 操作 描述 inner join 只返回匹配的值 right join 会从右表中返回所有的值, 即使左表中没有匹配 left join 会从左表中返回所有的值, 即使右表中没有匹配 -- ========== 连表查询 join ======... -
SQL语法——left join on 多条件
2021-06-29 14:36:49(94条消息) SQL语法——left join on 多条件_minixuezhen的博客-CSDN博客 -
join on多个条件的理解
2020-06-12 16:03:28a表 b表 查询1: 这是一个简单的左连接,左表的数据都会查询在结果中。 查询2: 左连接,on后面跟了2个条件,其中第二个条件对左表...由此可见left join 的时候,on后面对左表的数据加筛选条件是没有用的。 查询3 -
【MySQL学习】JOIN ON详解
2020-04-10 15:30:55JOIN在MySQL中出现非常频繁,经常用于多表关联查询。 ...SELECT * FROM a LEFT JOIN b ON a.id = b.id /*RIGHT JOIN * 右关联,此时b表为主表,a、b关联后的临时表中b表所有数据均存在*/ SELEC... -
MySQL中的LEFT JOIN ON (where)查询
2019-10-23 10:41:28LEFT JOIN ON的使用语法: select [需要查询的字段] from [table_name1] left join [table_name2] on [两个表关联的条件] (where [进一步对查询结果过滤的条件]) LEFT JOIN关键字会从左表(table_name1)那里... -
Mybatis踩坑记:JOIN ON 后多条件要加()
2020-05-28 13:30:10前述: 今天遇到一个诡异的问题,mybatis按...原来是我LEFT JOIN ON后面有多个筛选条件,这里一定要将ON后面的筛选条件加(),不然mybatis处理时逻辑会不正确! 总述: 知其然,还要知其所以然 特此记录 ... -
left join on 后增加条件分析
2018-10-27 10:40:33对left/right join on 后面增加左表或右表条件后,或者多个left/right join 表不同的位置查询结果 感觉到很不解,因此我对以下左连接做了分析演示: 1.两个表的左连接的查询。 2.两个表左连接,在on后面增加左表... -
SQL语句join on和where的区别
2018-11-12 17:13:36连接的作用是,同时查询多个表的数据。 left join :左连接,返回左表中所有的记录以及右表中连接字段相等的记录。 ...full join:外连接,返回两个表中的行:left join + right join。 cross ... -
left join on详解
2018-06-28 09:51:57把left join左边的表的记录全部找出来。系统会先用表A和表B做个笛卡儿积,然后以表A为基表,去掉笛卡儿积中表A部分为NULL的记录。最后形成你的结果。 进行左连接时,就有涉及到主表、辅表,这时主表条件写在WHERE... -
join on和where执行顺序
2019-01-29 14:05:011、join中相比where优先推荐on WHERE子句中使用的连接语句,在数据库语言中,被称为隐性连接。INNER JOIN……ON子句产生的连接称为显性连接。(其他JOIN参数也是显性连接)WHERE和INNER JOIN产生的连接关系,没有... -
MySQL多个left join on关联条件的顺序
2019-12-18 11:49:14注意:下面的案例特别重要!...例如表A,B,C,A left join B on A.x = B.x left join C on A.x = C.x,B和C的都要和A建立关联,B和C之间是没有任何数据上的关系。但是 如果把A.x = C.x改成B.x = C.... -
left join on多个条件怎么写
2020-08-15 17:49:19有时我们不仅需要用一个字段去...left join ( select id,name,code from table2 ) b on a.id = b.id and a.code = b.code 有时候on出错的话,可以用cast on cast(a.id as varchar(40)) = cast(b.id as varchar(40)) and -
多个left join on使用时的顺序问题
2018-10-31 12:11:27版权声明:本文为博主原创文章,未经博主允许不得转载。... ...连续多个left join on使用时候的顺序 在实际工作中,很多情况下会用到外连接,尤其是做主页面的数据展示查询...