整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          那一年,為了進(jìn)阿里背過的SQL題

          大家好,我是大鵬,周末看到朋友轉(zhuǎn)發(fā)的?篇文章:《那些年,為了進(jìn)阿里背過的面試題》。

          本文作者公眾號

          感嘆失敗的原因可能有很多,而做成的道路只有?條,那就是不斷積累。純手工的8291字的SQL面試題總結(jié)分享給初學(xué)者,俗稱八股文,期待對新手有所幫助。

          (公眾號后臺回復(fù):SQL面試題可獲取完整PDF資料)

          窗口函數(shù)題

          窗口函數(shù)其實(shí)就是根據(jù)當(dāng)前數(shù)據(jù), 計(jì)算其在所在的組中的統(tǒng)計(jì)數(shù)據(jù)。

          窗口函數(shù)和group by得區(qū)別就是,groupby的聚合對每一個組只有一個結(jié)果,但是窗口函數(shù)可以對每一條數(shù)據(jù)都有一個結(jié)果。

          商品類別數(shù)據(jù)集一. 從數(shù)據(jù)集中得到每個類別收入第一的商品和收入第二的商品。

          當(dāng)前系統(tǒng)的日期_當(dāng)前日期時間_使用期限不能早于系統(tǒng)當(dāng)前日期

          思路:計(jì)算每一個類別的按照收入排序的序號,然后取每個類別中的前兩個數(shù)據(jù)。

          總結(jié)答案:

          SELECT
          ??product,
          ??category,
          ??revenue
          FROM?(
          ??SELECT
          ????product,
          ????category,
          ????revenue,
          ????dense_rank()?OVER?w?as?'rank'
          ??FROM?productRevenue
          WINDOW?w?as?(PARTITION?BY?category?ORDER?BY?revenue?DESC)
          )?tmp
          WHERE
          ??'rank'?<=?2;

          按照類別進(jìn)行分組,且每個類別中的數(shù)據(jù)按照收入進(jìn)行排序,并為排序過的數(shù)據(jù)增加編號:

          SELECT?product,
          ?category,
          ?revenue,
          ?dense_rank()?OVER?w?as?'rank'
          FROM?productRevenue
          WINDOW?w?as?(PARTITION?BY?category?ORDER?BY?revenue?DESC);

          根據(jù)編號,取得每個類別中的前兩個數(shù)據(jù)作為最終結(jié)果;

          二. 統(tǒng)計(jì)每個商品和此品類最貴商品之間的差值

          當(dāng)前日期時間_使用期限不能早于系統(tǒng)當(dāng)前日期_當(dāng)前系統(tǒng)的日期

          總結(jié)答案:

          SELECT
          ????product,
          ????category,
          ????revenue,
          ????MAX(revenue)?OVER??w?-?revenue?as?revenue_difference
          FROM?productRevenue
          WINDOW?w?as?(PARTITION?BY?category?ORDER?BY?revenue?DESC);

          首先創(chuàng)建窗口,按照類別進(jìn)行分組,并對價格倒敘排列;

          應(yīng)用窗口,求出每個組內(nèi)的價格最大值,對其減去商品的價格,起別名。

          用戶表(時長,用戶id)查詢某一天中時長最高的60% 用戶的平均時長

          總結(jié)答案:

          with?aa?as(
          ??select
          ????*,
          ????row_number()?over(
          ??????order?by
          ????????時長?desc
          ????)?as?rank_duration
          ??from
          ????表
          ??where
          ????package_name?=?'com.miHoYo.cloudgames.ys'
          ????and?date?=?20210818
          )
          select
          ??avg(時長)
          from
          ??aa
          where
          ??rank_duration?<=?(
          ????select
          ??????max(rank_duration)
          ????from
          ??????aa
          ??)?*?0.6;

          這是排名問題,排名問題可以考慮用窗口函數(shù)去解決。

          將問題拆分為:

          1) 找出時長前60%的用戶;

          2) 剔除訪問次數(shù)前20%的用戶

          首先找某天的數(shù)據(jù),按時長降序從高到低進(jìn)行排名,注意要用,相相等的話也會往后算數(shù):

          select
          ????*,
          ????row_number()?over(
          ??????order?by?duration?desc
          ????)?as?rank_duration
          ??from
          ????表
          where
          ????package_name?=?'com.miHoYo.cloudgames.ys'
          ????and?date?=?20210818;

          排完名后,要找出前60%的用戶:

          **用戶排名值=內(nèi)連接)

          列出受雇日期早于其直接上級的所有員工編號、姓名、部門名稱

          思路一:第一步將****emp a看成員工表,將emp b 看成領(lǐng)導(dǎo)表,員工表的mgr字段應(yīng)該等于領(lǐng)導(dǎo)表的主鍵字段

          select?
          ????e.empno,
          ????e.ename
          from
          ????emp?e
          join
          ????emp?b
          on
          ????e.mgr?=?b.empno
          where
          ????e.hiredate?+-------+-------+
          |?empno?|?ename?|
          +-------+-------+
          |??7369?|?SMITH?|
          |??7499?|?ALLEN?|
          |??7521?|?WARD??|
          |??7566?|?JONES?|
          |??7698?|?BLAKE?|
          |??7782?|?CLARK?|
          |??7876?|?ADAMS?|
          +-------+-------+

          第二步:顯示上面員工的部門名稱,將****emp a員工表和dept d進(jìn)行關(guān)聯(lián)

          select?
          ????d.dname,
          ????e.empno,
          ????e.ename
          from
          ????emp?e
          join
          ????emp?b
          on
          ????e.mgr?=?b.empno
          join
          ????dept?d
          on
          ????e.deptno?=?d.deptno
          where
          ????e.hiredate?+------------+-------+-------+
          |?dname??????|?empno?|?ename?|
          +------------+-------+-------+
          |?ACCOUNTING?|??7782?|?CLARK?|
          |?RESEARCH???|??7369?|?SMITH?|
          |?RESEARCH???|??7566?|?JONES?|
          |?RESEARCH???|??7876?|?ADAMS?|
          |?SALES??????|??7499?|?ALLEN?|
          |?SALES??????|??7521?|?WARD??|
          |?SALES??????|??7698?|?BLAKE?|
          +------------+-------+-------+

          列出部門名稱和這些部門的員工信息,同時列出那些沒有員工的部門

          select?
          ????d.dname,(部門名稱)
          ????e.*(該部門的員工信息)
          from
          ????emp?e
          right?join
          ????dept?d
          on
          ????e.deptno?=?d.deptno;
          (需要讓所有的部門顯示出來,因此需要用右外連接)
          內(nèi)連接和外連接分別省略了inner和outer關(guān)鍵字

          列出至少有5個員工的所有部門

          第一步:先求出每個部門有多少員工,將****emp a和部門表 dept d表進(jìn)行關(guān)聯(lián),條件是e.deptno=d.deptno

          第二步:然后通過分組e.deptno,過來count(e.ename) >= 5

          select?
          ????e.deptno,count(e.ename)?as?totalEmp
          from
          ????emp?e
          group?by
          ????e.deptno
          having
          ????totalEmp?>=?5;
          +--------+----------+
          |?deptno?|?totalEmp?|
          +--------+----------+
          |?????20?|????????5?|
          |?????30?|????????6?|
          +--------+----------+
          2?rows?in?set

          這里比較關(guān)鍵:第一點(diǎn) 使用了group by 字段,select 后面的字段只能是group by后面的字段e.deptno和聚合函數(shù)對應(yīng)的字段count(e.ename) as

          第二點(diǎn):現(xiàn)在要對聚合函數(shù)的結(jié)果進(jìn)行過濾,字段不是數(shù)據(jù)庫中的字段,不能使用where進(jìn)行限制,只能使用having。

          (子查詢)列出薪水比“SMITH”多的所有員工信息

          第一步:首先求出是,smith的工資

          第二步:然后求出工資高于simith的

          select?*?from?emp?where?sal?>?(select?sal?from?emp?where?ename?=?'SMITH');

          列出所有"CLERK"(辦事員)的姓名及其部門名稱,部門人數(shù)

          答案

          select?t1.deptno,?t1.dname,?t1.ename,?t2.totalEmp
          from?(
          ??????select?d.deptno,?d.dname,?e.ename
          ??????from?emp?e
          ??????join?dept?d
          ??????on?e.deptno?=?d.deptno
          ??????where?e.job?=?'CLERK'
          ?????)t1
          join?(
          ??????select?e.deptno,?count(e.ename)?as?totalEmp
          ??????from?emp?e
          ??????group?by?e.deptno
          ?????)t2
          on?t1.deptno?=?t2.deptno;

          1、第一步在emp a表中查詢出那些人的job崗位是辦事員

          2、將emp a表和dept d表相關(guān)聯(lián)就可以得到職位是辦事員的emp對應(yīng)的部門名稱

          使用期限不能早于系統(tǒng)當(dāng)前日期_當(dāng)前系統(tǒng)的日期_當(dāng)前日期時間

          3、查詢出每個部門對應(yīng)的員工總數(shù)

          4、將第三步的查詢結(jié)果作為一個臨時表t與第二步的查詢結(jié)果進(jìn)行關(guān)聯(lián),關(guān)聯(lián)條件是t.deptno = d.deptno

          第一步先找出這一幫人

          select?d.deptno,?d.dname,?e.ename
          from?emp?e
          join?dept?d
          on?e.deptno?=?d.deptno
          where?e.job?=?'CLERK';

          第二步求出每個部門的員工數(shù)量

          select?e.deptno,?count(e.ename)?as?totalEmp
          from?emp?e
          group?by?e.deptno;
          最后匯總,把t1表換成第一個sql,t2換成第二個sql:
          select?t1.deptno,?t1.dname,?t1.ename,?t2.totalEmp
          from?t1
          join?t2
          on?t1.deptno?=?t2.deptno;

          (子查詢)列出最低薪水大于1500的各種工作及從事此工作的全部雇員人數(shù)

          第一步:先求出每個工作崗位的最低薪水,把>1500的留下

          select?e.job,?min(e.sal)?as?minsal
          from?emp?e
          group?by?e.job
          having?minsal?>?1500;

          第二步:添加count聚合函數(shù),來查看人數(shù)

          select?e.job,?min(e.sal)?as?minsal,?count(e.ename)as?totalEmp
          from?emp?e
          group?by?e.job
          having?minsal?>?1500

          (子查詢)列出在部門“SALES”工作的員工的姓名,假定不知道銷售部門的部門編號

          答案

          select?ename?from?emp?
          where?deptno?=?(
          ????select?deptno?from?dept?where?dname?=?'SALES'
          );

          第一步:先求出部門的部門編號;

          select?deptno?from?dept?where?dname?=?'SALES';
          +--------+
          |?deptno?|
          +--------+
          |?????30?|
          +--------+

          第二步:再從部門select部門中的員工姓名;

          select?ename?from?emp?where?deptno?=?(select?deptno?from?dept?where?dname?=?'SALES');
          +--------+
          |?ename??|
          +--------+
          |?ALLEN??|
          |?WARD???|
          |?MARTIN?|
          |?BLAKE??|
          |?TURNER?|
          |?JAMES??|

          (經(jīng)典)列出薪金高于公司平均薪金的所有員工,所在部門、上級領(lǐng)導(dǎo)、雇員的工資等級

          答案

          select?e.ename,d.dname,?b.ename?as?leadername,?s.grade
          from?emp?e
          join?dept?d
          on?e.deptno?=?d.deptnp
          left?join?emp?b
          on?e.mgr?=?b.empno???????--員工的領(lǐng)導(dǎo)編號?等于?領(lǐng)導(dǎo)的員工編號
          join?salgrade?s
          on?e.sal?between?s.losal?and?s.hisal
          where?e.sal?>(select?avg(sal)?as?avgsal?from?emp);

          第一步:求出薪金高于公司平均薪金的所有員工

          第二步:把第一步的結(jié)果當(dāng)成臨時表t 將臨時表t和部門表 dept d 和工資等級表salary s進(jìn)行關(guān)聯(lián),求出員工所在的部門,雇員的工資等級等

          關(guān)聯(lián)的條件是t.deptno = d.deptno t.salary s.lower and high;

          第三步:求出第一步條件下的所有的上級領(lǐng)導(dǎo),因?yàn)橛械膯T工沒有上級領(lǐng)導(dǎo)需要使用left join 左連接

          第一步:求出公司的平均薪水
          select?avg(sal)?as?avgsal?from?emp;
          +-------------+
          |?avgsal??????|
          +-------------+
          |?2073.214286?|
          +-------------+
          第二步:列出薪水高于平均薪水的所有員工
          select?e.ename
          from?emp?e
          where?e.sal?>(select?avg(sal)?as?avgsal?from?emp);
          第三步:列出所有員工的所在部門(需要join on)
          select?e.ename,d.dname
          from?emp?e
          join?dept?d
          on?e.deptno?=?d.deptnp
          where?e.sal?>(select?avg(sal)?as?avgsal?from?emp);
          第四步:列出所有員工的上級領(lǐng)導(dǎo)(需要join on)
          select?e.ename,d.dname,?b.ename?as?leadername
          from?emp?e
          join?dept?d
          on?e.deptno?=?d.deptnp
          join?emp?b
          on?e.mgr?=?b.emp???????--員工的領(lǐng)導(dǎo)編號?等于?領(lǐng)導(dǎo)的員工編號
          where?e.sal?>(select?avg(sal)?as?avgsal?from?emp);
          第五步:要求列出所有員工,在第二個join,員工表是emp e表,否則會只顯示有領(lǐng)導(dǎo)的員工
          select?e.ename,d.dname,?b.ename?as?leadername
          from?emp?e
          join?dept?d
          on?e.deptno?=?d.deptnp
          left?join?emp?b
          on?e.mgr?=?b.empno???????--員工的領(lǐng)導(dǎo)編號?等于?領(lǐng)導(dǎo)的員工編號
          where?e.sal?>(select?avg(sal)?as?avgsal?from?emp);
          第六步:雇員的工資等級
          select?e.ename,d.dname,?b.ename?as?leadername,?s.grade
          from?emp?e
          join?dept?d
          on?e.deptno?=?d.deptnp
          left?join?emp?b
          on?e.mgr?=?b.empno???????--員工的領(lǐng)導(dǎo)編號?等于?領(lǐng)導(dǎo)的員工編號
          join?salgrade?s
          on?e.sal?between?s.losal?and?s.hisal
          where?e.sal?>(select?avg(sal)?as?avgsal?from?emp);

          列出與“SCOTT”從事相同工作的所有員工及部門名稱

          step1:查詢出SCOTT的工作崗位

          select?job?from?emp?where?ename?=?'SCOTT';
          +---------+
          |?job?????|
          +---------+
          |?ANALYST?|
          +---------+

          step2:部門名稱(需要join部門表)

          select?
          ????d.dname,
          ????e.*
          from
          ????emp?e
          join
          ????dept?d
          on
          ????e.deptno?=?d.deptno
          where
          ????e.job?=?(select?job?from?emp?where?ename?=?'SCOTT');

          列出薪金中等于第30號部門中員工的薪金的其它員工的姓名和薪金

          答案

          select?ename,?sal?from?emp
          where?sal?in
          (select?distinct?sal
          from?emp
          where?deptno?=?30)
          and
          deptno?<>?30;

          第一步:先知道第30號部門中員工的薪金有哪幾種值

          select?distinct?sal
          from?emp
          where?deptno?=?30;

          第二步:顯示姓名和薪水

          select?ename,?sal?from?emp
          where?sal?in
          (
          ????select?distinct?sal?from?emp?where?deptno?=?30
          );

          第三步:需要滿足"其他員工"的條件

          select?ename,?sal?from?emp
          where?sal?in
          (
          ????select?distinct?sal?from?emp?where?deptno?=?30
          )
          and
          deptno?<>?30;

          列出薪金高于在第30號部門中工作的所有員工的薪金的員工姓名和薪金、部門名稱

          第一步:找出部門30中的最高薪水

          select?max(sal)?as?maxsal
          from?emp
          where?deptno?=?30;

          第二步:要輸出的是員工姓名,因需要把emp表作為主表

          select?d.dname,?e.ename,?e.sal
          from?emp?e
          join?dept?d
          on?e.deptno?=?d.deptno
          where?e.sal?>?(select?max(sal)?as?maxsal
          from?emp;

          (關(guān)鍵)列出在每個部門工作的員工數(shù)量、平均工資和平均服務(wù)期限

          答案

          select?d.deptno,?count(e.ename),
          ??????ifnull(avg(e.sal),0)?as?avgsal,
          ??????avg(ifnull((to_days(now())-to_days(hiredate))/365,0))?as?serverTime
          from?emp?e
          right?join?dept?d
          on?e.deptno?=?d.deptno
          group?by?d.deptno;

          第一步:求出每個部門對應(yīng)的所有員工,這里使用了右連接,保證顯示所有的部門,但是有的部門不存在員工,但是也必須把所有的部門顯示出來

          --?將員工表emp?e和部門表dept?d進(jìn)行表連接,將員工表和部門表信息全部展示
          select?e.*,?d.*
          from?emp?e
          right?join?dept?d
          on?e.deptno?=?d.deptno;

          第二步:在第一步的基礎(chǔ)上求出所有員工的數(shù)量,這里因?yàn)橛械牟块T員工是null,所有不能使用count(*),count(*)統(tǒng)計(jì)包含null,應(yīng)該使用count(e.ename)

          --?列出每個部門工作的員工數(shù)量
          select?d.deptno,?count(e.ename)
          from?emp?e
          right?join?dept?d
          on?e.deptno?=?d.deptno
          group?by?d.deptno;

          第三步:求出員工的平均工資,因?yàn)橛械牟块T員工不存在,所以對應(yīng)的工作也是null,這里需要null值做處理

          處理:
          IFNULL(expr1, expr2),如果expr1不是Null,IFNULL()返回expr1,否則返回expr2。
          --?列出每個部門工作的員工數(shù)量
          select?d.deptno,?count(e.ename),
          ??????ifnull(avg(e.sal),0)?as?avgsal
          from?emp?e
          right?join?dept?d
          on?e.deptno?=?d.deptno
          group?by?d.deptno;

          第四步:求出每個員工的平均服務(wù)期限:平均服務(wù)期限,每個人從入職到今天,一共服務(wù)了多少年。相加除以部門人數(shù)。

          當(dāng)前日期時間_使用期限不能早于系統(tǒng)當(dāng)前日期_當(dāng)前系統(tǒng)的日期

          處理:
          IFNULL(expr1, expr2),如果expr1不是Null,IFNULL()返回expr1,否則返回expr2。
          --?to_days(日期類型)?->?天數(shù)
          --?獲取數(shù)據(jù)庫的系統(tǒng)當(dāng)前時間的函數(shù)
          select?to_days(now());
          --?算出員工工作多少天
          select?ename,?(to_days(now())-to_days(hiredate))/365?as?serveryear
          from?emp;
          --算出員工工作多少年
          select?avg((to_days(now())-to_days(hiredate))/365)as?serveryear?from?emp
          最終:
          select?d.deptno,?count(e.ename),
          ??????ifnull(avg(e.sal),0)?as?avgsal,
          ??????avg(ifnull((to_days(now())-to_days(hiredate))/365,0))?as?serverTime
          from?emp?e
          right?join?dept?d
          on?e.deptno?=?d.deptno
          group?by?d.deptno
          注意:
          count(*)?計(jì)算行的數(shù)目,包含?NULL
          count(column)?特定的列的非空值的行數(shù),不包含?NULL?值。

          列出所有員工姓名、部門名稱和工資

          --?注意是所有員工
          select?d.dname,e.ename,e.sal
          from?emp?e
          right?join?dept?d
          on?e.deptno?=?d.deptno

          列出所有部門的詳細(xì)信息和人數(shù)

          統(tǒng)計(jì)人數(shù)的時候不能使用count(*),而要使用count(e.ename)字段的值,同時
          select?
          ????d.deptno,d.dname,d.loc,count(e.ename)?as?totalEmp
          from
          ????emp?e
          right?join
          ????dept?d
          on
          ????e.deptno?=?d.deptno
          group?by
          ????d.deptno,d.dname,d.loc;
          +--------+------------+----------+----------+
          |?deptno?|?dname??????|?loc??????|?totalEmp?|
          +--------+------------+----------+----------+
          |?????10?|?ACCOUNTING?|?NEW?YORK?|????????3?|
          |?????20?|?RESEARCH???|?DALLAS???|????????5?|
          |?????30?|?SALES??????|?CHICAGO??|????????6?|
          |?????40?|?OPERATIONS?|?BOSTON???|????????0?|

          列出各種工作的最低工資及從事此工作的雇員姓名

          第一步:求出各種工作的最低工資

          select?
          ????e.job,min(e.sal)?as?minsal
          from
          ????emp?e
          group?by?
          ????e.job;
          +-----------+---------+
          |?job???????|?minsal??|
          +-----------+---------+
          |?ANALYST???|?3000.00?|
          |?CLERK?????|??800.00?|
          |?MANAGER???|?2450.00?|
          |?PRESIDENT?|?5000.00?|
          |?SALESMAN??|?1250.00?|
          +-----------+---------+

          第二步將以上查詢結(jié)果當(dāng)成臨時表t(job,minsal)

          select?
          ????e.ename
          from
          ????emp?e
          join
          ????(select?
          ????????e.job,min(e.sal)?as?minsal
          ????from
          ????????emp?e
          ????group?by?
          ????????e.job)?t
          on
          ????e.job?=?t.job
          where
          ????e.sal?=?t.minsal;
          +--------+
          |?ename??|
          +--------+
          |?SMITH??|
          |?WARD???|
          |?MARTIN?|
          |?CLARK??|
          |?SCOTT??|
          |?KING???|
          |?FORD???|

          列出各個部門Manager的最低薪金

          各個部門,需要進(jìn)行分組;

          select?e.deptno,?min(e.sal)?as?minsal
          from?emp?e
          where?e.job?=?'Manager'
          group?by?e.deptno;

          列出所有員工的年薪,按年薪從低到高進(jìn)行排序

          薪水為年薪+補(bǔ)助,給補(bǔ)助加上空值處理函數(shù)。

          select?ename,?(sal?+?ifnull(comm,?0))*12?as?yearsal?from?emp?
          order?by?yearsal?asc;

          求出員工領(lǐng)導(dǎo)的薪水超過3000的員工名和領(lǐng)導(dǎo)名

          先求出員工所對應(yīng)的領(lǐng)導(dǎo),最后再把員工領(lǐng)導(dǎo)的薪水超過3000的選出。

          員工表連接領(lǐng)導(dǎo)表,員工的領(lǐng)導(dǎo)編號等于領(lǐng)導(dǎo)的員工編號

          select?e.ename,?b.ename?as?leadername
          from?emp?e
          join?emp?b
          on?e.mgr?=?b.empno
          where?b.sal?>?3000;

          求部門名稱中帶's'字符的部門員工的工資合計(jì)、部門人數(shù)

          先求出部門中帶s的有哪些部門;

          select?d.dname,?sum(e.sal)?as?sumsal,?count(e.ename)?as?totalEmp
          from?emp?e
          join?dept?d
          on?e.deptno?=?d.deptno
          where?d.dname?like?'%s%'
          group?by?d.dname;

          給任職日期超過30年的員工加薪10%

          修改需要用到update語句,

          create table as select * from emp;

          update?emp_bak1?set?sal?=?sal?*?1.1?
          where?(to_days(now())-to_days(hiredate))/365?>30;?

          學(xué)生表

          有3個表S(學(xué)生表),C(課程表),SC(學(xué)生選課表):

          S(SNO,SNAME)代表(學(xué)號,姓名)

          C(CNO,CNAME,)代表(課號,課名,教師)

          SC(SNO,CNO,SCGRADE)代表(學(xué)號,課號,成績)

          找出沒選過“黎明”老師的所有學(xué)生姓名。

          第一種做法:子查詢

          黎明老師的授課的編號 -->先找出選過黎明老師的學(xué)生編號 --> 在學(xué)生表中找出

          一、找出黎明老師的授課的編號
          select?cno?from?c?where?cteacher?=?'黎明';
          二、再找出選過黎明老師的學(xué)生編號
          select?sno?from?sc?where?cno?in?(select?cno?from?c?where?cteacher?=?'黎明');
          三、集合
          select?*?from?s?where?sno?not?in(select?sno?from?sc?where?cno?=?(select?cno?from?c?where?cteacher?=?'黎明'));

          第二種做法--表連接做法:

          第一步:找到黎明老師所上課對應(yīng)的課程對應(yīng)的課程編號
          select?cno?from?c?where??cteacher?=?'黎明';
          第二步:求出那些學(xué)生選修了黎明老師的課程
          select?sno?from?sc?join(
          ????select?cno?from?c?where??cteacher?=?'黎明'
          )t?on?sc.cno?=?t.cno;
          第三步:求出那些學(xué)生沒有選擇黎明老師的課
          select?sno,sname?from?s?where?sno?not?in(select?sno?from?sc?join(?select?cno?from?c?where??cteacher?=?'黎明')?t
          on?sc.cno?=?t.cno);

          列出2門以上(含2門)不及格學(xué)生姓名及平均成績

          思路一 :在sc表中首先按照學(xué)生編號進(jìn)行分組,得到哪些學(xué)生的有兩門以上的成績低于60分

          第一步:先查詢學(xué)生不及格的門數(shù)??
          select?
          ?????sc.sno?,count(*)?as?studentNum
          from?
          ?????sc?
          where?
          ??????scgrade?60
          group?by
          ??????sc.sno
          having
          ??????studentNum?>=?2;
          (現(xiàn)在只得到了學(xué)生編號,需要在s表中找到學(xué)生姓名)
          第二步:查詢出該學(xué)生對應(yīng)的編號
          select?
          ????a.sno?,?a.sname
          from
          ????s?as?a
          join
          ???(
          ??????select?
          ????????????sc.sno?,count(*)?as?studentNum
          ????????from?
          ?????????????sc?
          ????????where?
          ??????????????scgrade?60
          ????????group?by
          ??????????????sc.sno
          ????????having
          ??????????????studentNum?>=?2
          ?????
          ???)?as?b
          on
          ???a.sno?=?b.sno;???
          +-----+----------+
          |?sno?|?sname????|
          +-----+----------+
          |???1?|?zhangsan?|
          +-----+----------+
          1?row?in?se

          第三步得到該學(xué)生的平均成績,把上面的表當(dāng)成臨時表m

          select?
          ???m.sno,m.sname,avg(d.scgrade)
          from
          ???sc?as?d
          join
          ???(
          ????????select?
          ????????????a.sno?,?a.sname
          ????????from
          ????????????s?as?a
          ????????join
          ???????????(
          ??????????????select?
          ????????????????????sc.sno?,count(*)?as?studentNum
          ????????????????from?
          ?????????????????????sc?
          ????????????????where?
          ??????????????????????scgrade?60
          ????????????????group?by
          ??????????????????????sc.sno
          ????????????????having
          ??????????????????????studentNum?>=?2
          ?????????????
          ???????????)?as?b
          ????????on
          ???????????a.sno?=?b.sno
          ???
          ???)??as?m
          on
          ??m.sno?=?d.sno???
          group?by
          ???d.sno?;

          簡單寫法:

          select?t1.snmae,?t2.avgscgrade
          from?t1
          join?t2
          on?t1.sno=t2.sno;

          既學(xué)過1號課程又學(xué)過2號課所有學(xué)生的姓名

          select?s.sname?from?
          ????sc?
          join
          ????s
          on
          ????sc.sno?=?s.sno
          where?
          ????cno?=?1?and?sc.sno?in(select?sno?from?sc?where?cno?=?2);

          (姓名不在sc表中,因此需要用到j(luò)oin)

          不能寫成下面的形式會存在錯誤

          select sno from sc where cno=1 and cno =2;

          分段用戶數(shù)

          給你兩個表,表A為:uid, age;表B:uid、、dtm。表B有100億條,需求:每10歲為一年齡段,要每個年齡段的活躍用戶數(shù)、使用應(yīng)用數(shù)、使用應(yīng)用的總次數(shù)

          select?
          ?count(distinct?B.uid)?as?活躍用戶數(shù),
          ?count(distincct?B.package_name)?as?使用應(yīng)用數(shù),
          ?count(B.dtm)?as?使用應(yīng)用的總次數(shù)
          from?B
          join?(
          ?select?A.uid,
          ?????case?when?age?<=?10?and?age?>?10?then?'0-10'
          ?????when?age?<=?20?and?age?>?10?then?'10-20'
          ?????when?age?>?20?and?age?<=?30?then?'20-30'
          ?????when?age?>?30?and?age?<=?40?then?'30-40'
          ?????else?'40+'?END?as?age_stage?
          From?A)?as?C
          on?C.uid?=?B.uid
          group?by?age_stage;

          時間戳考察把時間得int數(shù)據(jù)轉(zhuǎn)化為時間戳


          主站蜘蛛池模板: 精品一区中文字幕| 天天综合色一区二区三区| 国产成人一区二区三区视频免费 | 精品国产一区二区三区无码| 午夜视频在线观看一区| 好吊视频一区二区三区| 无码乱码av天堂一区二区| 大屁股熟女一区二区三区| 在线精品一区二区三区| 精品福利一区二区三| 秋霞鲁丝片一区二区三区| 亚洲国产精品无码第一区二区三区| 在线播放一区二区| 日本精品一区二区三区在线观看| 日本精品3d动漫一区二区| 国产福利一区二区三区在线观看| 中文字幕日韩人妻不卡一区| 午夜视频久久久久一区 | 视频一区二区三区免费观看| 无码国产精品一区二区免费式影视| 亚州国产AV一区二区三区伊在| 亚洲一区二区在线视频| 国产一区二区三区在线2021 | 免费一区二区三区| 国产女人乱人伦精品一区二区| 一区二区三区在线观看| 亚洲一区欧洲一区| 成人区精品一区二区不卡亚洲| 亚洲午夜在线一区| 亚洲一区二区三区乱码在线欧洲| 久久精品一区二区三区AV| 亚洲爆乳精品无码一区二区| 成人精品一区二区激情| 国产一区内射最近更新| 国产天堂一区二区综合| 国产一区二区免费| 好爽毛片一区二区三区四无码三飞| 国产精品一区二区四区| 视频一区二区三区在线观看| 国产一区二区三区在线看| 中文激情在线一区二区|