SQL 基础--> 子查询

--=========================

--SQL 基础--> 子查询

--=========================

一、子查询

子查询就是位于SELECT、UPDATE、或DELETE语句中内部的查询

二、子查询的分类

单行子查询

返回零行或一行

多行子查询

返回一行或多行

多列子查询

返回多列

相关子查询

引用外部SQL语句中的一列或多列

嵌套子查询

位于其它子查询中的查询

三、子查询语法

SQL>

SELECT select_list

FROM table

WHERE expr operator (SELECT select_list FROM table);

子查询(内部查询)在执行主查询之前执行一次,然后主查询(外部查询)会使用该子查询的结果

四、子查询的规则

将子查询括在括号中

将子查询放置在比较条件的右侧

只有在执行排序Top-N分析时,子查询中才需要使用ORDER BY 子句

单行运算符用于单行子查询,多行运算符用于多行子查询

五、单行子查询

仅返回一行

使用单行的表较运算符:= ,>, >= ,< , <= ,<>

--在WHERE 子句中使用子查询

SQL>

select ename, job

from emp

where empno = (select empno from emp where mgr = 7902);

--使用分组函数的子查询

SQL>

select ename, job, sal from emp where sal > (select avg(sal) from emp);

--在HAVING子句中使用子查询

SQL>

select deptno, min(sal)

from emp

group by deptno

having min(sal) > (select min(sal) from emp where deptno = 20);

--在FROM 子句中使用子查询

SQL>

select empno, ename from (select empno, ename from emp where deptno = 20);

--单行子查询中的常见错误

--子查询的结果返回多于一行

SQL>

select empno, ename

from emp

where sal = (select sal from emp where deptno = 20);

(select sal 返回多行

ORA-01427: single-row subquery returns more than one row

--子查询中不能包含ORDER BY子句

SQL>

select empno, ename

from emp

where sal > (select avg(sal) from emp order by empno);

order by empno)

ORA-00907: missing right parenthesis

--子查询内部没有返回行,如下语句可以正确执行,但没有数据返回

SQL>

select ename, job

from emp

where empno = (select empno from emp where mgr = 8000);

返回:no rows selected

六、多行子查询

返回多个行

使用多行比较运算符IN ,ANY ,ALL

--在多行子查询中使用IN 操作符

SQL>

select empno, ename, job

from emp

where sal in (select max(sal) from emp group by deptno);

--在多行子查询中使用ANY 操作符

备注:

{

比如集合(1,2,3,4)

>any表示只要大于其中任意一个就行

>all表示要比其中的任何一个都大

}

SQL>

select empno, ename, job

from emp

where sal < any (select avg(sal) from emp group by deptno);

--在多行子查询中使用ALL 操作符

SQL>

select empno, ename, job

from emp

where sal > all (select avg(sal) from emp group by deptno);

七、相关子查询

子查询中使用了主查询中的某些字段,主查询每扫描一行都要执行一次子查询

--查询工资高于同一部门的员工的平均工资的 部门号,姓名,工资

SQL>

select deptno, ename, sal

from emp

outer where sal > (select avg(sal)

from emp

inner where inner.deptno = outer.deptno);

--查询负责管理其它员工的员工记录(使用exists)

注:EXISTS 是判断是否存在,和in类似,但效率要比in高

SQL>

select empno, ename

from emp

outer where exists

(select empno from emp inner where inner.mgr = outer.empno);

--查询不管理其它员工的职员(not exists)

SQL>

select empno, ename

from emp

outer where not exists

(select empno from emp inner where inner.mgr = outer.empno)

备注:EXISTS 和NOT EXISTS 与IN 和NOT IN 的比较

EXISTS与IN的不同:

EXISTS只检查行的存在性,IN 要检查实际值的存在性(一般情况下EXISTS的性能高于IN)

NOT EXISTS 和NOT IN:

当值列表中包含空值的情况下,NOT EXISTS 则返回true,而NOT IN 则返回false.

--看下面的查询,查询部门号不在emp表中出现的部门名称及位置

SQL>

select deptno, dname, loc

from dept d

where not exists (select 1 from emp e where e.deptno = d.deptno);

--IN与空值

SQL>

SELECT *

FROM emp e

WHERE e.empno NOT IN (SELECT 7369

FROM dual

UNION ALL

SELECT NULL FROM dual);

SQL>

SELECT * FROM emp e WHERE e.empno IN (‘7369‘, NULL);

注:子查询要包含在括号内

子查询一般放在比较条件的右侧

除非进行TOP-N 分析,否则不要在子查询中使用ORDER BY。

八、多列子查询

1、成对比较

--查询工资为部门最高的记录

SQL>

select *

from scott.emp

where (sal, job) in (select max(sal), job from scott.emp group by job);

--非成对比较,实现了与上述类似的功能

SQL>

select *

from scott.emp

where sal in (select max(sal) from scott.emp group by job)

and job in (select distinct job from scott.emp);

九、嵌套子查询

即位于子查询内部的子查询,嵌套层数最多可达层。然而应尽量避免使用嵌套子查询,使用表连接的查询性能会更高

SQL>

select deptno, Num_emp

from (select deptno, count(empno) as Num_emp from emp group by deptno) d

where Num_emp > 3;

注意:子查询对空值的处理除了count(*)外,都会忽略掉空值

时间: 2024-10-12 16:02:57

SQL 基础--> 子查询的相关文章

06. SQL 基础--&gt; 子查询

一.子查询 子查询就是位于SELECT.UPDATE.或DELETE语句中内部的查询 二.子查询的分类 单行子查询 返回零行或一行 多行子查询 返回一行或多行 多列子查询 返回多列 相关子查询 引用外部SQL语句中的一列或多列 嵌套子查询 位于其它子查询中的查询 三.子查询语法 SELECT select_list FROM table WHERE expr operator (SELECT select_list FROM table); 子查询(内部查询)在执行主查询之前执行一次,然后主查询

SQL Fundamentals: 子查询 || 行列转换(PIVOT,UNPIVOT,DECODE),设置数据层次(LEVEL...CONNECT BY)

SQL Fundamentals || Oracle SQL语言 子查询(基础) 1.认识子查询 2.WHERE子句中使用子查询 3.在HAVING子句中使用子查询 4.在FROM子句中使用子查询 5.在SELECT子句中使用子查询 6.WITH子句 子查询(进阶) 7.分析函数 8.行列转换 9.设置数据层次 八.行列转换 pivot和unpivot函数是Oracle 11g增加的新函数,利用此函数可以实现行列转换操作 按照原始方式实现,使用通用函数中的DECODE()函数 列字段的处理 SQ

SQL用子查询结果更新多个字段

作者:iamlasong 要求:表格的内容需要变更,变更的内容放在一个临时表中,用SQL语句更新正式表中多个字段. 如果更新一个字段,直接用字段名=子查询就可以了,多个字段更新,将字段在括号中并列写出即可,如下: update tb_jg t set t.jgfl = 'sd', (     t.zj_code, t.zj_mc) = (select a.zj_code, a.zj_mc from song_temp a where a.zj_code = t.zj_code) where ex

SQL优化-子查询&case&limit

load 导数据.notesdxtdb 数据库    total_time  475.60秒. 监控服务:仓颉 select t_.*, a.name acquirer_name,m.merchant_name, am.merchant_name acq_merchant_name,                   ag.name agency_name            from              (            select t.* ,               

SQL Fundamentals: 子查询 || 分析函数

子查询(基础) 1.认识子查询 2.WHERE子句中使用子查询 3.在HAVING子句中使用子查询 4.在FROM子句中使用子查询 5.在SELECT子句中使用子查询 6.WITH子句 子查询(进阶) 7.分析函数 8.行列转换 9.设置数据层次 七.分析函数 分析函数语法: 分窗操作的: 使用分析函数可以进行更为复杂的查询报表显示. 在分析函数中可以使用若干统计函数. 传统SQL的问题 虽然利用SQL之中提供的各种查询命令可以完成大部分的查询要求,但是还有许多功能是无法实现的,例如: 计算运行

SQL Server子查询填充DataSet时报500内部错误的解决办法

运行环境为Visual Studio 2010,数据库为SQL Server 2008. 执行下面SQL语句 SELECT SubsiteId, SubsiteTitle, count(CollectionID) CollectionNumber,count(LName) PlantNumber FROM (SELECT DISTINCT SubsiteId, SubsiteTitle, CollectionID, LName, CName FROM Cumplag_Garden_Plants

ThinkPHP3.2 SQL alias 子查询

SELECT info_key, info_value, info_status, edit_time FROM (SELECT * FROM `detail` WHERE login = '[email protected]' ORDER BY edit_time DESC  ) AS aaa GROUP BY info_key 希望通过Thinkphp实现基于alias的子查询,终于参考下面这个文章实现了. http://www.thinkphp.cn/update/122.html 如下是

SQL 数据库 子查询及示例

子查询,又叫做嵌套查询. 将一个查询语句做为一个结果集供其他SQL语句使用,就像使用普通的表一样,被当作结果集的查询语句被称为子查询. 子查询有两种类型: 一种是只返回一个单值的子查询,这时它可以用在一个单值可以使用的地方,这时子查询可以看作是一个拥有返回值的函数: 另外一种是返回一列值的子查询,这时子查询可以看作是一个在内存中临时存在的数据表. 示例: --创建一个数据库,建立一个部门表格和部门人员表格 Create database gongs --创建一个gongs的数据库 go use

SQL随着子查询结果更新多个字段

笔者:iamlasong 要求:表格内容需要改变,在临时表中内容的变化,使用SQL官方声明更新表若干领域. 假设更新一个字段,直接用字段名=子查询就能够了,多个字段更新,将字段在括号里并列写出就可以,例如以下: update tb_jg t set t.jgfl = 'sd', (     t.zj_code, t.zj_mc) = (select a.zj_code, a.zj_mc from song_temp a where a.zj_code = t.zj_code) where exi