1. 程式人生 > >sql的嵌套查詢,把一次查詢的結果做為表繼續進一步查詢;內聯視圖

sql的嵌套查詢,把一次查詢的結果做為表繼續進一步查詢;內聯視圖

實驗 單獨 gets pro 參考 autotrace https data ray

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的嵌套查詢,把一次查詢的結果做為表繼續進一步查詢;內聯視圖