mysql加強(6)~子查詢簡單介紹、子查詢分類

一、子查詢簡單介紹

1、什麼是子查詢?

一個查詢之中嵌套了其他的若干查詢。

  • 在使用select 語句查詢時,有時候where的查詢條件中的限制條件不是一個確定的值,而是一個來自於另一個查詢的結果。
  • 子查詢一般出現在fromwhere 子句中。

2、子查詢語法:

select <select_list>

from 表名

where 條件(s) 操作符

​ (select <select_list> from 表名);

  • 子查詢在主查詢前執行,然後主查詢再使用子查詢的結果。

3、子查詢例子:

# 查詢大於公司平均工資的員工姓名
select ename, sal from emp where sal > (select avg(sal) from emp);

4、子查詢經典案例—Oracle的分頁查詢


5、子查詢的使用注意事項:

  • 子查詢需要用括弧括起來
  • 將子查詢放在比較運算符的右邊【增強可讀性】
  • 對單行子查詢使用單行運算符
  • 對多行子查詢使用多行運算符

二、子查詢的分類

1、子查詢的分類【根據子查詢的結果集來劃分】

(1)單行單列子查詢:子查詢返回一行一列記錄,好比就是一個值

  • 返回一條記錄—比較運算符(針對一個值的運算符): = > < >= < !=

    # 查詢大於公司平均工資的員工姓名
    select ename, sal from emp where sal > (select avg(sal) from emp);
    


(2) 多行單列子查詢:子查詢返回單列多行記錄,好比是多個值

  • 返回多條記錄—比較運算符(多個值的運算符): in any all

  • in 相當於 = any

  • any:與子查詢返回的任意一個值做比較; all:與子查詢返回的每一個值做比較

    # 查詢工資等於部門經理的員工資訊
    select * from emp where sal in (select sal from emp where job = 'manager');
    select * from emp where sal = any (select sal from emp where job = 'manager');
    # 查詢工資大於任意部門經理的員工資訊
    select * from emp where sal > any (select sal from emp where job = 'manager');
    # 查詢工資小於任意部門經理的員工資訊
    select * from emp where sal < any (select sal from emp where job = 'manager');
    


(3)多行多列子查詢:子查詢返回多列一行/多行記錄,好比是一張表 【其實就是多表連接查詢

  • 一般把查詢結果含多個列的當做臨時表必須給臨時表起個別名】,接著在臨時表上繼續查詢或者連接查詢;

    # 查詢出每個部門的編號、名稱、部門人數、平均工資
    select t.deptno, d.dname, t.count_empno, t.avg_sal
    from dept d  left join
    (select e.deptno, count(e.empno) count_empno, avg(e.sal) avg_sal from emp e group by deptno) t
     on d.deptno = t.deptno;
    

2、union/union all

  • join 是橫向連接,union/union all 是縱向連接(一般用於作為臨時表)
  • 注意:
    • union 內部的select 語句必須是擁有相同數量的列
    • 列也必須擁有兼容的數據類型
    • 每條select語句中的列的順序必須相同
    • union 結果集的列名總是等於union中第一個select語句的列名
    • union操作符選去不同的值,若允許值重複-使用union all 性能更高

  • 語法:

    select <select_list> from 表名1

    union | union all

    select <select_list> from 表名2

  • 全連接–mysql不止全連接,不過可以使用左右連接+union實現

    #全連接查詢員工的編號、名稱、部門名稱
    select e.deptno,e.ename,d.dname from emp e left join dept d on e.deptno = d.deptno
    union
    select e.deptno,e.ename,d.dname from emp e right join dept d on e.deptno = d.deptno;