`
qiang106
  • 浏览: 383830 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

子查询转换为连接查询

阅读更多
   我们进行数据查询的时候极少有可能就在一张表里就能得到想要的数据,不可避免得会用到子查询或者连接查询,很多时候我们很轻松自然得会想到子查询的方法,但是子查询往往效率比较低,而转换成连接查询是一种很好的优化方式。

    子查询转换成连接查询又可以分为两种情况,一种是不带聚合的子查询转换,另一种就是带有聚合函数的转换

一、不带聚合函数的子查询转换:

以下是一组测试数据:
use mytest;
drop table  if exists jobs;
CREATE TABLE jobs(
	employee varchar(30),
	title varchar(30)
);
drop table if exists ranks;
CREATE TABLE ranks(
	title varchar(30),
	rank varchar(30)
);
drop table if exists salary;
CREATE TABLE salary(
	rank varchar(30),
	payment int(11)
);

insert into jobs values('张三','经理'),('李四','总经理'),('王五','总经理助理');
insert into ranks values('经理','三'),('总经理','一'),('总经理助理','二');
insert into salary values('一',20000),('二',8000),('三',7000),('四',7000);



   建立了三个表,分别是jobs员工工作表,记录了员工的工作,第二表ranks是岗位等级表,记录每一个工作岗位的等级,第三个表slary自然就是HR为每一个等级的定的薪资标准了。

    现在要知道张三的工资是多少,就需要使用三张表才能得到数据,
使用子查询的方法如下:

select payment from salary 
	where rank=(
		SELECT rank from ranks 
			where title=(
				SELECT title from jobs 
					where employee='张三')
);


转换为连接查询的步骤大致有如下几点:
1、使用表名或者表别名标记所有的列,如显jobs.employee 或者j.employee;
2、将几个子查询的From子名中使用的相同的表用同一个名字或同一别名;
3、将几个Form子句放在一起;
4、将Select及查询的列删除;
5、将第一个之后的Where替换成AND

最后得到如下结果:
select payment from salary s,ranks r,jobs j 
	where j.employee='张三' 
		and j.title = r.title 
		and s.rank = r.rank;


对于需要排除某些条件的查询,如查询岗位等级表中在薪资表中没有工资级别的等级:
select salary.rank 
	from salary 
		where rank 
			not in(select rank from ranks);

使用not in、exists、not exists不失为一种好方法,但同样可以转换成连接查询。如以上的查询可以转换为:
select salary.rank 
	from salary left join ranks 
		on salary.rank=ranks.rank 
			where ranks.rank is null;


二、带聚合函数的子查询向连接查询转换

如下测试数据,有一个订单表,记录了销售人员每天的销售记录,测试数据如下:

DROP TABLE if exists orders;
create table orders(
	customer varchar(30),
	whn date,
	totalitems int(11)
);
insert into orders values('jj','2010-10-10',5),
			('jj','2010-10-11',3),
			('jj','2010-10-12',1),
			('aa','2010-10-10',5),
			('bb','2010-10-10',8),
			('cc','2010-10-10',10);



需要查询每一个销售员最高销售额的日期及销售额时,必然用的聚合函数MAX,以下是最容易想到的查询方式:
select customer,whn,totalitems 
	from orders o1 where o1.totalitems=(
		SELECT max(totalitems) 
			from orders o2 
				where o1.customer = o2.customer
);

此时需要对每一行订单都要进行子查询,因此代码运行速度会很慢,并且老版本的MySQL还不支持子查询,只有一个表,要改成连接查询自然就是自连接了,这里我们需要使用Having子句,
select o1.* from orders o1 join orders o2 
	on(o1.customer=o2.customer) 
		group by o1.customer 
			having o1.totalitems=max(o2.totalitems
);


相信这些我们大学的时候都已经学过,但是没有真正用起来的时候总是那么容易忘记,没有实际操作和体验是感觉不到它的需要,自然也不长记性了,而写下来又是另一种记住的方式。
分享到:
评论

相关推荐

    SQL子查询、内连接和外连接查询

    2.体会各种查询的异同及相互之间的转换,体会各种查询的执行过程,为综合应用打下良好的基础。 ● 查询没有选修指定课程号的学生的学号、姓名、性别、出生日期和级别。课程号由局部变量提供。 declare @Cno char...

    精通SQL 结构化查询语言详解

    10.2.2 IN子查询实现集合交和集合差运算 10.2.3 EXISTS子查询  10.2.4 EXISTS子查询实现两表交集  10.2.5 SOME/ALL子查询  10.2.6 UNIQUE子查询  10.3 相关子查询  10.3.1 使用IN引入相关子查询  ...

    精通sql结构化查询语句

    9.6.2 内连接与右外连接的综合应用 9.6.3 UNION集合运算与多表连接应用 9.7 小结第10章 子查询 10.1 子查询的简单应用 10.1.1 子查询概述 10.1.2 在多表查询中使用子查询 10.1.3 在子查询中使用聚合函数 10.1.4 使用...

    Oracle数据库Sql语句详解大全

    第六章 子查询 第七章 数据建模及数据库设计 了解系统开发的步骤 数据关系的定义 理解实体关系映射图(E-R图) 第八章 创建表 掌握创建表的语法 Oracle的数据类型 使用约束 第九章 对数据的操作 在已创建表中插入...

    海量数据库解决方案_韩国_李华植

    3.3.7 查询转换(query transformation)过程中提示的使用214 3.3.8 其他提示216 第4章 构建索引的战略方案221 4.1 索引的选定准则222 4.1.1 不同类型表的索引应用准则223 4.1.2 离散度和损益分界点227 4.1.3 索引合并...

    sql-to-mongodb:将SQL表转换为MongoDB集合的Java工具

    将SQL表转换为MongoDB集合的Java工具 轻松将 MSSQL 表转换为 MongoDB。 从下载 SQL Server JDBC 驱动程序 将 SQLJDBC4.jar 文件放在同一文件夹中。 一次指定 TABLE NAME 和 NUMBER OF ROWS 进行导入。 java -...

    精通SQL--结构化查询语言详解

    10.2.2 in子查询实现集合交和集合差运算 191 10.2.3 exists子查询 192 10.2.4 exists子查询实现两表交集 194 10.2.5 some/all子查询 195 10.2.6 unique子查询 197 10.3 相关子查询 198 10.3.1 使用in引入相关...

    SQL普查优化信息汇总

    如果查询中包含了子查询,那么注意首先优化子查询 注意关联子查询,尽量减少关联子查询的使用,因为它的代价很高,并且非常消耗CPU 在Sql语句中使用not exists 代替 not in 用表连接替换EXISTS 使用带有前导字段的...

    IT-数据库(1).docx

    IT-数据库(1) IT-数据库(1)全文共44页,当前为第1页。IT-数据库(1)全文共44页,当前为第1... HDR集群中参数DRAUTO设置为2,若此时关闭HDR主机,则___ A.HDR备用数据库将转换为主用模式,原HDR主用恢复成备用模式 B.由连

    Oracle数据库SQL语句优化策略

    ORACLE 试图将其转换成多个表的连接,如果转换不成功则先执行IN里面的子查询,再查询外层的表记录,如果转换成功则直接采用多个表的连接方式查询。由此可见用 IN的SQL至少多了一个转换的过程。一般的SQL都可以转换...

    PL-SQL(由DBA8[1].CN提供,DBA吧,DBA的出没之地) word格式

    第七章 子查询 11  单行子查询 11  多行子查询 11  多列子查询 12  NULL值 13  嵌套的子查询 13 第八章 表的创建和维护 15  表设计 15  创建表 16  修改现有的表 17  删除表 19 第九章 约束 20 ...

    (第一卷)Microsoft.SQL.Server.2008技术内幕:T-SQL语言基础

    主要包括SQL的基础理论、逻辑查询处理、SELECT查询、连接和子查询、表表达式、过滤和分组、透视转换、修改数据、事务和一致性的处理、可编程对象等内容。  书中并非系统地罗列T-SQL的各种语法元素,而是结合实践中...

    sql脚本优化

    sql试图将其转换成多个表的连接,如果转换不成功则先执行IN里面的子查询,再查询外层的表记录,如果转换成功则直接采用多个表的连接方式查询。由此可见用IN的SQL至少多了一个转换的过程。一般的SQL都可以转换成功,...

    程序员的SQL金典.rar

    透彻分析函数、子查询、表连接、不同DBMS中的SQL语法差异、SQL调优、NULL值处理、事务、开窗函数等高级技术;通过对实际案例开发过程的详细分析,使读者掌握 SQL的综合应用技巧。 内容简介 本书主要介绍SQL的语法...

    CRM课程设计报告完整版

    (3)SQL语句要求规范,标点正确,查询语句应包含简单查询、连接查询、子查询、复合条件查询。语句内容自定,并写出语句的功能。 (4)报告的文档包括:数据库的应用背景介绍,数据库设计方案,添加、修改、删除和查询...

    程序员的SQL金典6-8

     11.1.8 为查询编号  11.1.9 标记所有单内最大销售量  11.2 排序  11.2.1 非字段排序规则  11.2.2 随机排序  11.3 表间比较  11.3.1 检索制作过采购单的人制作的销售单  11.3.2 检索没有制作过采购单的人...

    程序员的SQL金典7-8

     11.1.8 为查询编号  11.1.9 标记所有单内最大销售量  11.2 排序  11.2.1 非字段排序规则  11.2.2 随机排序  11.3 表间比较  11.3.1 检索制作过采购单的人制作的销售单  11.3.2 检索没有制作过采购单的人...

    OCA认证考试指南1Z0-051

    8.2 描述子查询能够解决的问题的类型 8.2.1 将子查询的结果集用于比较 8.2.2 星型转换(StarTransformation) 8.2.3 生成执行SELECT语句的表 8.2.4 生成投影值 8.2.5 生成传递给DML语句的行 8.3 列举子...

Global site tag (gtag.js) - Google Analytics