sql的嵌套查询,把一次查询的结果做为表继续进一步查询;内联视图

Posted 沧海一粟,何以久远

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了sql的嵌套查询,把一次查询的结果做为表继续进一步查询;内联视图相关的知识,希望对你有一定的参考价值。

mysql的嵌套表查询

  嵌套SELECT语句也叫子查询,一个 SELECT 语句的查询结果能够作为另一个语句的输入值。子查询可以:

  • 出现在Where子句中,
  • 出现在from子句中,作为一个临时表使用,
  • 出现在select list中,作为一个字段值来返回。

示例

1、出现在where子句中

  • 单行子查询 :单行子查询是指子查询的返回结果只有一行数据。当主查询语句的条件语句中引用子查询结果时可用单行比较符号(=, >, <, >=, <=, <>)来进行比较。
select ename,deptno,sal from emp where deptno=(select deptno from dept where loc=\'NEW YORK\');
  • 多行子查询:多行子查询即是子查询的返回结果是多行数据。当主查询语句的条件语句中引用子查询结果时必须用多行比较符号(IN,ALL,ANY)来进行比较。其中,IN的含义是匹配子查询结果中的任一个值即可("IN" 操作符,能够测试某个值是否在一个列表中),ALL则必须要符合子查询的所有值才可,ANY要符合子查询结果的任何一个值即可。而且须注意ALL 和ANY 操作符不能单独使用,而只能与单行比较符(=、>、< 、>= 、<= 、<>)结合使用
select stName from Student where stId in (select distinct stId from score where teId=(select teId from teacher where teName=\'Rona\'));

 

select stName from Student where stId in (select distinct stId from score where score >all (select score from score where stId=(select stId from Student where stName= \'Kaka\')));

 

select stName from Student where stId in (select distinct stId from score where score >any(select score from score where stId=(select stId from Student where stName=\'Kaka\')));
  • 多列子查询:当是单行多列的子查询时,主查询语句的条件语句中引用子查询结果时可用单行比较符号(=, >, <, >=, <=, <>)来进行比较;当是多行多列子查询时,主查询语句的条件语句中引用子查询结果时必须用多行比较符号(IN,ALL,ANY)来进行比较。
SELECT deptno,ename,job,sal FROM EMP WHERE (deptno,sal) IN (SELECT deptno,MAX(sal) FROM EMP GROUP BY deptno);

 

2、内联视图:出现在where子句中,查询结果作为子表(临时表)。示例包含联合查询、嵌套查询

select job_name1,app_name,plugin_name,plugin_version from (select job_name as job_name1, app_name as app_name,plugin_name as plugin_name,plugin_version as plugin_version from plugin_check  left join jobs  on  project_name=job_name) as suibianxie where plugin_name LIKE \'%graylog-logback%\' AND `plugin_version` < \'1.0.27.3\' ORDER BY app_name

 

去重复操作distinct详解

1、作用于单列自然好理解,作用于多列时,是根据多列来去重的,比如下面两列是不重复的

select distinct col1,col2,col3 from table_test
a 1 c
a 1 b

2、且distinct并非是对多列“字符串拼接”后再去重的,而是分别作用于了每一列,比如下面两列是不重复的;下面两列拼接后是相同的,但是并不会被判断会相同

select distinct col1,col2 from table_test
rain m
rai  nm

3、distinct必须放在开头

 

普通视图内联视图(in-line view)的关系

在select语句里的内联视图(in-line view),即SELECT * FROM (<select clause> ),例如

SELECT * 
  FROM ( SELECT deptno, count(*) emp_count
         FROM emp
         GROUP BY deptno ) emp,
       dept
 WHERE dept.deptno = emp.deptno;
其中,
( SELECT deptno, count(*) emp_count FROM emp GROUP BY deptno )就是所谓的内联视图(in-line view)。

在DML语句里的内联视图(in-line view),例如

nsert into (<select clause> ) values (...),其具体示例如下:

insert into (select object_id,object_name,object_type from xxx where object_id<1000)
values(1001,\'testbyhao\',\'testtype\');

普通视图

我们平时说的视图指的是create view语句创建的视图类型,我们暂且称其为普通视图。例如,

CREATE  VIEW     empvu30
 AS SELECT  employee_id, last_name, salary
 FROM    employees
WHERE   department_id = 30;

普通视图本质上还是内联视图(in-line view),因为在执行包含普通视图的SQL语句时,普通视图都会最终转化为内联视图(in-line view)。例如,

在select语句里的普通视图,例如,

SELECT *  FROM    empvu30;
最终转化为
SELECT *  FROM  (SELECT  employee_id, last_name, salary  FROM    employees WHERE   department_id = 30);

在DML语句里的普通视图,例如,

insert into  empvu30 values(129,‘jak’,50000);
最终转化为
insert into (SELECT  employee_id, last_name, salary  FROM    employees WHERE   department_id = 30) values(129,‘jak’,50000);

 

内联视图(in-line view)和子查询的区别

内联视图(in-line view)(各种类型的视图本质上都是内联视图)不同于子查询的地方在于:
子查询(可以视之为)是一个中间结果集,但是内联视图(in-line view)不可这么认为。这点可以从如

insert into (select object_id,object_name,object_type from xxx where object_id<1000) values (999,\'testbyhao\',\'testtype\');

时看出,因为一个select语句执行所得的结果集是只能读取而不能被修改的,即不支持DML操作,但是内联视图(in-line view)却又是支持DML操作,所以说从内联视图(in-line view)这个特性来看,它更像是表,只不过内联视图(in-line view)没有实际的数据,视图的全部家当,也就是你创建视图时的SELECT语句,故而我们可以将内联视图(in-line view)视为一张虚拟的表。

注释:

View
A view is a named and validated SQL query which is stored in the Oracle data dictionary. Views do not contain any data - it is just a stored query in the database that can be executed when called. One can think of a view as a virtualtable or mapping of data from one or more tables.

参见:http://www.orafaq.com/wiki/View

下面的实验证明了内联视图(in-line view)更像是表而不是子查询:
为什么说内联视图(in-line view)没有实际执行呢?看统计信息吧:
SQL> set autotrace trace exp stat
SQL> select object_id,object_name,object_type from xxx where object_id<1000;
955 rows selected.
97 consistent gets
这是一个结果集,有955 rows selected(被选择了).
SQL>create table ts as (select object_id,object_name,object_type from xxx where object_id<1000);
SQL> insert into ts values(999,\'testbyhao\',\'testtype\');

1 row created.
1 consistent gets

SQL> insert into (select object_id,object_name,object_type from xxx where object_id<1000)2 values(999,\'testbyhao\',\'testtype\');1 row created.1 consistent gets

从这里看出,内联视图(in-line view)的特性更像是表而不是子查询,因为insert into 内联视图(in-line view)时的统计信息说明内联视图(in-line view)没有像子查询那样实际执行而获得一个含有955行数据的结果集。insert into 内联视图(in-line view)时的统计信息显示1 row created.即新创建了一行数据在视图里,这个和insert into 表时的统计信息一样。
注释:
内联视图(in-line view)中内联的意思,在主查询语句中,内联视图(in-line view):
( SELECT deptno, count(*) emp_count FROM emp GROUP BY deptno )
是直接将其源码
( SELECT deptno, count(*) emp_count FROM emp GROUP BY deptno )嵌入主查询语句中,而普通视图,如名为empvu30的视图:
CREATE VIEW empvu30 AS SELECT  employee_id, last_name, salary FROM    employees WHERE   department_id = 30;是将视图名 empvu30嵌入主查询语句中,而不是其源码
SELECT  employee_id, last_name, salary FROM    employees WHERE   department_id = 30;
所以,内联视图(in-line view)中内联的意思就是直接将内联视图源码嵌入主查询语句里的意思。内联函数中内联的意思也是如此,即直接将内联函数的函数体源码嵌入到类中,而不是在类中只是声明了函数头,没有函数体。这样,可以避免在类中只是声明了函数头而没有函数体时要保护现场后去切换调用函数体的开销,从而提高执行速度。



 

参考:

1、https://www.cnblogs.com/wangshenhe/archive/2012/11/28/2792093.html

2、http://wiki.jikexueyuan.com/project/sql/sub-queries.html

3、https://blog.csdn.net/sinat_25059791/article/details/69666318

以上是关于sql的嵌套查询,把一次查询的结果做为表继续进一步查询;内联视图的主要内容,如果未能解决你的问题,请参考以下文章

sql语句 怎么在第一次查询完的结果 以外的内容中继续查询

SQL ---子查询

Mybatis 的嵌套查询与嵌套结果的区别

Mybatis 的嵌套查询与嵌套结果的区别

如何在查询中取消嵌套嵌套表的集合?

SQL 数据库 子查询及示例