數(shù)據(jù)庫操作(七)

回顧:
1、sql的執(zhí)行順序
select ⑤
from ①
where ②
group by ③
having ④
order by ⑥

2、關(guān)聯(lián)查詢
多表聯(lián)合查詢,杜絕笛卡爾積現(xiàn)象。
要求N張表聯(lián)合,必須至少有N-1個(gè)連接條件。
內(nèi)連接:查詢出所有滿足連接條件的數(shù)據(jù)。

外連接:查詢出數(shù)據(jù),滿足+不滿足條件的數(shù)據(jù)
左外連接
左表驅(qū)動(dòng)表(所有數(shù)據(jù))+ 右表匹配表(匹配)
右外連接
左表匹配表(匹配)+ 右表驅(qū)動(dòng)表(所有數(shù)據(jù))
全外連接
左表驅(qū)動(dòng)表(所有數(shù)據(jù))+ 右表驅(qū)動(dòng)表(所有數(shù)據(jù))
自連接
特殊連接查詢
驅(qū)動(dòng)、匹配表都來自于同一張表。

正課:
1、子查詢
你是sql大牛,能否寫一條select sql就能查詢出想要的數(shù)據(jù)。
如:查詢30部門最大工資的員工信息。
--錯(cuò)

    select *,max(sal) from emp 
        where deptno = 30;
select * from emp where deptno = 30
        and sal = (
            --30部門最高工資
            select max(sal) from emp 
            where deptno = 30
        );

如上所述:
當(dāng)無法使用一條select sql完成一個(gè)功能時(shí),
可以考慮使用sql嵌套的方式來完成。

sql嵌套:
一條SQL語句中嵌套著另一條SQL查詢語句。
又被稱為---子查詢。

被嵌套在SQL語句中的查詢SQL,稱為子查詢,
子查詢所在的那條SQL語句,稱為父查詢。

注意:子查詢可以使用在DDL、DML、DQL中,
通常一般使用在DQL中為多。

1)、子查詢使用在DDL中

    create table emp_copy
        as (select empno,ename,job,sal,deptno 
            from emp
            );

結(jié)論:子查詢使用在建表語句中,
實(shí)為表結(jié)構(gòu)、表數(shù)據(jù)的復(fù)制。

2)、子查詢使用在DML中

    insert into emp_copy 
        --values 注意:連values都沒有
        (
            select empno,ename,job,sal,deptno 
            from emp
        );

3)、子查詢使用在DQL中
DQL結(jié)構(gòu)
select
from
where
group by 不使用子查詢
having
order by 不使用子查詢r(jià)

子查詢的分類
   根據(jù)子查詢的結(jié)果,可將子查詢分為:

①、單行單列子查詢。
select max(sal) from emp
where deptno = 30;--查詢30部門的最高工資(1個(gè))
②、多行單列子查詢。
select empno from emp
where deptno = 30;--查詢30部門的員工編號(hào)(多個(gè))
③、多行多列子查詢。
select empno,ename,sal,deptno
from emp
where deptno = 30;--查詢30部門的員工信息(編號(hào),姓名,工資,部門編號(hào))(多條)

3-1)、子查詢使用在where子句中
--查詢與JONES員工相同部門的其他員工信息。
--step1:查詢JONES員工所在部門
select deptno from emp where ename='JONES';
--step2:部門等于JONES部門的員工(其他員工)
select * from emp where deptno = (step1的結(jié)果)
and ename <> 'JONES';
--step3:sql拼接。

       select * from emp 
        where deptno = (
            --單行單列子查詢
            select deptno from emp where ename='JONES'
        )
        and ename <> 'JONES';

--查詢與SMITH、ALLEN不在同一個(gè)部門的員工信息。
--step1:查詢出SMITH、ALLEN所在部門
select deptno from emp
where ename = 'SMITH' or ename = 'ALLEN';--in ('SMITH'、'ALLEN')

--step2:查詢不在SMITH、ALLEN部門的員工
select * from emp
where deptno not in (step1的結(jié)果);
--step3:sql拼接
select * from emp
where deptno not in (
--多行單列子查詢
select deptno from emp
where ename = 'SMITH' or ename = 'ALLEN'
);
注意:where子句中,可以出現(xiàn)單行單列、多行單列子查詢。
單行單列子查詢,一般使用 =、!=、<...
多行單列子查詢,一般使用 in、any、all。

    ***補(bǔ)充:
       在子查詢中,需要引入主查詢的某些字段數(shù)據(jù)。
        可以使用exists關(guān)鍵字。
    
       --查詢有員工的部門信息
       方式一:內(nèi)連接方式
        select d.* from emp e,dept d
        where e.deptno = d.deptno;

       方式二:使用exists關(guān)鍵字
        select * from dept d
        where exists --存在以下關(guān)系
        (
            --只需要存在這種關(guān)系即可
            --能有返回值,說明關(guān)系存在
            --所以無需關(guān)系確切的返回?cái)?shù)據(jù)內(nèi)容
            select 1 from emp e
            where e.deptno = d.deptno
        );

3-2)、子查詢使用在having子句中
--查收出最低薪水 高于 30部門最低薪水
的部門信息(部門編號(hào)、最低薪水)。
--step1:查詢出30部門的最低薪水
select min(sal) from emp where deptno=30;

--step2:查詢出各部門的最低薪水
select deptno,min(sal)
from emp
group by deptno;

--step3:最低薪水對(duì)比
select deptno,min(sal)
from emp
--where 后面無法使用聚合函數(shù)
--where min(sal) > (step1的結(jié)果)
group by deptno
--但是having可以使用聚合函數(shù)
having min(sal) > (step1的結(jié)果);

--step4:sql拼接

       select deptno,min(sal) 
        from emp 
        --where 后面無法使用聚合函數(shù)
        --where min(sal) > (step1的結(jié)果)
        group by deptno
        --但是having可以使用聚合函數(shù)
        having min(sal) > (
            select min(sal) from emp 
            where deptno=30
        );

3-3)、子查詢使用from子句中
from 后面跟 表(多行多列結(jié)構(gòu))
所以一般多行多列子查詢會(huì)充當(dāng)臨時(shí)表(虛表、匿名視圖)
的功能,使用在from后面。

多行多列子查詢作為臨時(shí)表,該表并不存在,
查詢到的數(shù)據(jù),也只能在當(dāng)前sql中有效。

--查詢與30部門員工職位、工資都相同的
其他部門員工信息。
--step1:先查出30部門的職位及工資
select job,sal from emp
where deptno=30;
--step2:查詢其他部門中員工信息
select * from emp
where deptno <> 30;
--step3:職位與工資匹配
select o.*
from (step2結(jié)果) o --其他部門人員,
(step1結(jié)果) th --30部門職位及工資
where o.job = th.job
and o.sal = th.sal;
--step4:sql

        select o.* 
        from (select * from emp 
            where deptno <> 30) o, --其他部門人員,
             (select job,sal from emp
            where deptno=30) th --30部門職位及工資
        where o.job = th.job
        and o.sal = th.sal;

3-4)、子查詢使用在select語句中
把子查詢放在select子句中,在一定程度上
可以充當(dāng)外連接效果。

    --查詢所有部門部門信息
    select distinct d.*,
    (select deptno from dept 
            where deptno not in(
            select distinct deptno from emp 
            where deptno is not null)) noEmpDept  
    from dept d,emp e
    where d.deptno = e.deptno;

    或給一個(gè)確切的值
    select distinct d.*,40 as noEmpDept  
    from dept d,emp e
    where d.deptno = e.deptno;

4、總結(jié):
1)、子查詢根據(jù)查詢結(jié)果可分為:
單行單列子查詢 (1個(gè)值)
多行單列子查詢 (多個(gè)值)
多行多列子查詢 (多條數(shù)據(jù))

2)、子查詢可以使用在DDL、DML、DQL中。
其中使用在DQL中居多。

3)、一條完整的DQL查詢語句,如下:
select
from
where
group by
having
order by
一般 group by、order by后面跟查詢表的字段名。
不能亂使用子查詢的結(jié)果。

     select、from、where、having中可以使用子查詢。
    a、其中where、having后面可以跟上
        單行單列子查詢 一般使用 =、!=、>、<等關(guān)系運(yùn)算符。
        多行單列子查詢 一般使用 in、not in、any、all

    b、from后面可以跟上
        多行多列子查詢 充當(dāng)臨時(shí)表。

    c、select后面只能跟上
        單行單列子查詢(一般不建議這么用)

補(bǔ)充:
1、刪除數(shù)據(jù)
truncate table emp_copy;--刪除數(shù)據(jù),保留表結(jié)構(gòu)
delete from emp_copy;--全表刪除數(shù)據(jù)
--truncate、delete的區(qū)別:
truncate不需要TCL支持
delete必須TCL支持

2、任何一個(gè)大功能sql都是由一個(gè)個(gè)小功能sql拼起來的。
一定要將功能進(jìn)行分解,分出一個(gè)個(gè)小功能。
將小功能先完成,最后做拼接。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容