SQL语句:子查询

一,子查询定义:

子查询就是嵌套在主查询中的查询。

子查询可以嵌套在主查询中所有位置,包括SELECT、FROM、WHERE、GROUP BY、HAVING、ORDER BY。

但并不是每个位置嵌套子查询都是有意义并实用的。

二,子查询的返回:

一个子查询会返回一个标量(单一值)、一个行、一个列或一个表(一行或多行及一列或多列)。这些子查询被称为标量、列、行和表子查询

1,单行单列,聚合(标量):

返回的结果集为单个的子查询,叫做单行子查询。单行比较符有: =、 >、>=、<、<=、!=

2,单行多列:

SELECT * FROM t1 WHERE (1,2) = (SELECT column1, column2 FROM t2);
SELECT * FROM t1 WHERE ROW(1,2) = (SELECT column1, column2 FROM t2);

如果在表t2的一个行中,column1=1并且column2=2,则查询结果均为TRUE。

表达式(1,2)和ROW(1,2)有时被称为行构造符。两者是等同的,在其它的语境中,也是合法的。例如,以下两个语句在语义上是等同的(但是目前只有第二个语句可以被优化):

SELECT * FROM t1 WHERE (column1,column2) = (1,1);
SELECT * FROM t1 WHERE column1 = 1 AND column2 = 1;

3,多行单列与多行多列:

返回的结果集为多个的子查询,为多行子查询,多行子比较符有 IN(等于列中任意一个)、ANY(和子查询返回的某个值比较),ALL(和子查询返回的所有值比较)

NOT IN是<> ALL的别名

IN是=ANY的别名

三,EXISTS和NOT EXISTS

如果一个子查询返回任何的行,则EXISTS subquery为FALSE。例如:

SELECT column1 FROM t1 WHERE EXISTS (SELECT * FROM t2);

四,关联子查询

相关联的子查询是一个包含对表的引用的子查询。该表也显示在外部查询中。例如:

SELECT * FROM t1 WHERE column1 = ANY (SELECT column1 FROM t2 WHERE t2.column2 = t1.column2);

注意,即使子查询的FROM子句不提及表t1,该子查询也会包含一个对t1中一列的引用。所以,MySQL看上去位于子查询的外部,并在外部查询中查找t1。

假设表t1包含一行,在此行中column1=5并且column2=6;同时,表t2包含一行,在此行中column1=5并且column2=7。简单的表达式... WHERE column1 = ANY (SELECT column1 FROM t2)会为TRUE。但是在本例中,在子查询中的WHERE子句为FALSE(因为(5,6)不等于(5,7)),所以子查询总体上为FALSE。

范围划分规则:MySQL从内到外进行评估。例如:

SELECT column1 FROM t1 AS x
WHERE x.column1 = (SELECT column1 FROM t2 AS x
WHERE x.column1 = (SELECT column1 FROM t3
WHERE x.column2 = t3.column1));

在本语句中,x.column2必须是表t2中的列,因为SELECT column1 FROM t2 AS x ...对t2进行了重命名。它不是表t1中的列,因为SELECT column1 FROM t1 ...是一个更靠外的外部查询。

对于HAVING或ORDER BY子句中的子查询,MySQL也会在外部选择清单中寻找列名称。

对于特定的情况,相关联的子查询被优化。例如:

val IN (SELECT key_val FROM tbl_name WHERE correlated_condition)

否则,这些子查询效率不高,可能速度会慢。把查询作为联合进行改写可能会改进效率。

相关联的子查询不能从外部查询中引用总计函数的结果。

五,FROM子句中的子查询

在SELECT语句的FROM子句中,子查询是合法的。实际的语法是:

SELECT ... FROM (subquery) [AS] name ...

[AS] name子句是强制性的,因为FROM子句中的每个表必须有一个名称。在子查询选择列表中的任何列都必须有唯一的名称。您可以在本手册中的其它地方找到对本语法的说明。在该处,所用的词语是“导出表”。

为了进行详细说明,假设您有如下一个表:

CREATE TABLE t1 (s1 INT, s2 CHAR(5), s3 FLOAT);

下面使用了示例表,解释了在FROM子句中如何使用子查询:

INSERT INTO t1 VALUES (1,‘1‘,1.0);
INSERT INTO t1 VALUES (2,‘2‘,2.0);
SELECT sb1,sb2,sb3
FROM (SELECT s1 AS sb1, s2 AS sb2, s3*2 AS sb3 FROM t1) AS sb
WHERE sb1 > 1;
//结果:2, ‘2‘, 4.0。

下面是另一个例子:假设您想了解一个分类后的表的一组和的平均值。采用如下操作:

SELECT AVG(SUM(column1)) FROM t1 GROUP BY column1;

不过,本查询提供所需的信息:

SELECT AVG(sum_column1)
FROM (SELECT SUM(column1) AS sum_column1
FROM t1 GROUP BY column1) AS t1;

注意,在子查询中使用的列名称(sum_column1)被整理到外部查询中。

FROM子句中的子查询可以返回标量、列、行或表。FROM子句中的子查询不能为有关联的子查询。

即使对EXPLAIN语句(即建立临时导出表),FROM子句中的子查询也会被执行。这是因为在优化过程中,上一级的查询需要有关所有表的信息。

原文地址:https://www.cnblogs.com/tkzc2013/p/10767336.html

时间: 2024-10-28 10:57:55

SQL语句:子查询的相关文章

基本sql语句--子查询

子查询有三种:where型子查询,from型子查询,exist子查询. where型子查询 where子查询:指把内层的查询结果当成外层查询的比较条件. 例句:查询出最新的商品:select good_id,good_name from good where good_id = (select max(good_id) from good);--此句为子查询 select good_id,good_name from good order by good_id DESC limit 1; fro

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 基础--&gt; 子查询

--========================= --SQL 基础--> 子查询 --========================= 一.子查询 子查询就是位于SELECT.UPDATE.或DELETE语句中内部的查询 二.子查询的分类 单行子查询 返回零行或一行 多行子查询 返回一行或多行 多列子查询 返回多列 相关子查询 引用外部SQL语句中的一列或多列 嵌套子查询 位于其它子查询中的查询 三.子查询语法 SQL> SELECT select_list FROM table WH

sql server 性能调优之 SQL语句阻塞查询

原文:sql server 性能调优之 SQL语句阻塞查询 在生产环境下,有时公司客服反映网页半天打不到,除了在浏览器按F12的Network响应来排查,确定web服务器无故障后.就需要检查数据库是否有出现阻塞 当时数据库的生产环境中主表数据量超过2000w,子表数据量超过1亿,且更新和新增频繁.再加上做了同步镜像,很消耗资源. 这时就要新建一个会话,大概需要了解以下几点: 1.当前活动会话量有多少? 2.会话运行时间? 3.会话之间有没有阻塞? 4.阻塞时间 ? 查询阻塞的方法有很多.有sql

SQL Server之 (二) SQL语句 模糊查询 空值处理 聚合函数

(二) SQL语句  模糊查询  空值处理  聚合函数 自己学习笔记,转载请注明出处,谢谢!---酸菜 SQL :结构化查询语言(Structured Query Language),关系数据库管理系统的标准语言. Sybase与Mircosoft对标准SQL做了扩展:T-SQL (Transact-SQL); 注:①SQL对大小写的敏感取决于排序规则,一般不敏感; ②SQL对单引号的转义,用两个单引号来表示一个单引号; ③SQL执行顺序: 1→2→3→4 select  * ---------

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语句联合查询详解

sql语句联合查询详解 2011-03-01 18:58:22|  分类: mysql|举报|字号 订阅 例子: person表和user表没有约束person表: user表: 有以下几种关联 1.UNION 格式:查询语句 UNION [ALL] 查询语句 [UNION [ALL] 查询语句][…n] 说明:ALL选项表示将所有行合并到结果集合中.不指定该项时,被联合查询结果集合中的重复行将只保留一行. 在包括多个查询的UNION语句中,其执行顺序是自左至右,使用括号可以改变这一执行顺序.例

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

在Hibernate中使用HibernateTemplate来进行包含sql语句的查询

/**     * 使用sql语句进行查询操作     * @param sql     * @return     */    public List queryWithSql(final String sql){        List list = hibernateTemplate.executeFind(new HibernateCallback() {            public Object doInHibernate(Session session) throws Hib

如何在 Linux 上用 SQL 语句来查询 Apache 日志

Linux 有一个显著的特点,在正常情况下,你可以通过日志分析系统日志来了解你的系统中发生了什么,或正在发生什么.的确,系统日志是系统管理员在解决系统和应用问题时最需要的第一手资源.我们将在这篇文章中着重讲解 Apache HTTP web server 生成的 Apache access 日志. 这次,我们会通过另类的途径来分析 Apache access 日志,我们使用的工具是 asql.asql 是一个开源的工具,它能够允许使用者使用 SQL 语句来查询日志,从而通过更加友好的格式展现相同