从前干技能的时候遇到很多复杂查询,join查询也是常用的,了解它们有助于工作的效率。
[size=1.176em]初探
假设存在这么两个表
人员表:Persons(pid,name,phone)
接洽方式表:phones(id,pid,phoneNo)
select * from Persons,phones where Persons.pid=phones.id
select * from table1 union(all) select * from table2// union只显示差别的行的效果集,而union all会将不会将相同的效果行剔除// 注意的是使用union和union all关键字时一定要确保union两边的sql选取的字段范例相同和字段// 总数相同
- inner join on(join两者相同)内连接
select * from Persons (inner) join phones on Persons.pid=phones.id // 只显示Person表中有电话号码的记录
这个在实际中用得比较多,比如要你显示所有的人,以及他们的所有的接洽方式。
sql可以这样写:
select * from Persons left join phones on Persons.pid=phones.id// 左连接的利益就是在于不论你所join表是否有记录都会显示出来,深受大家喜爱,个人屡试不爽
select * from Persons right join phones on Persons.pid=phones.id// 比如要你列出所有的接洽方式和对应的人// 他可以和left join on 互用,大多都被left join on 所代替
select * from Persons full join phones on Persons.pid=phones.id// 列出所有的人及他们的接洽方式以及所有的接洽方式 及它们对应的人
它们可以相互替换,但是用的不恰当速率会受到很大影响in是给定值中查询 恰当用于内大外小的情况,因为它是用外面的值来与子查询的中的值举行匹配exists恰当内小外大的情况,给定一个子查询来查找所给条件的子查询的行的存在
[size=1.176em]实操
需求如下:
A表数据要根据B表的记录有无来决定显示还是不显示
B表有A表的主键(此表外键),假如B表没有记录则查出数据
B表有数据则不要查询得到的数据。
既然要根据背面一张表的关联数据有无来决定数据的查询效果,果断选用left join ,但是left join 字句的查询数据有无对第一张表的查询无影响,只不外是在后表的字段显示空与不空的问题,还是解决不了整体数据显示问题:前一张表为grant,后表为trans 当中的表和字段都是胡扯的。
原始sql语句:
select t1.*,t3.* from grant t1 left join trans t3 on t3.order_id=t1.stake_id and t3.trans_type=3 and t3.status is not null inner join stake t2 on t2.id=t1.stake_id where t1.type=1;“t3.status is not null”为决定后表数据有无的决定条件,发现效果不佳,古思冥想,不显示数据就用inner join查询,显示数据就是left join查询,这不是矛盾吗?这可咋整,最后果断调整如下:
select t1.*,t3.* from grant t1 left join trans t3 on t3.order_id=t1.stake_id and t3.trans_type=3 inner join stake t2 on t2.id=t1.stake_id where t1.type=1 and t3.status is not null;问题解决,记住因为是判定背面的后一张表的记录是不是为空,所以条件一定要是null或是not null,假如写详细的值也会达不到预期的效果,服膺!
[size=1.176em]结论
其实造成这种缘故起因就会在于join后的条件筛选与where后的条件筛选对数据库实行计划顺序的影响,一般数据库实行sql语句之前会列出很多实行计划,然后根据最优的来实行,这就是常说的sql优化决定实行效率,第一个sql语句固然已将数据筛选,但是只是筛选子查询的条件,完全没影响到左边主表查询的效果,但是后者where的条件是控制整个语句的筛选,直接过滤。其实要是inner join的连接查询写前写后没任何区别,因为它是天然连接有就是有,没有就是没有,不存在这种情况。 |