網(wǎng)上流傳的50道SQL題刷一刷(使用mysql和hive)

  • 前言:因為hive支持開窗函數(shù)的緣故,會在某些場景比mysql省很多事仇冯,該篇以網(wǎng)上流傳的50道SQL題為例畏浆,比較SQL和HQL的實現(xiàn)。21題難度最大。
    附上萬能圖解:


    Join圖

一垮斯、數(shù)據(jù)表介紹

1.學(xué)生表
student(sid,sname,sage,ssex)
--sid 學(xué)生編號,sname 學(xué)生姓名,sage 出生年月,ssex 學(xué)生性別

2.課程表
course(cid,cname,tid)
--cid課程編號,cname課程名稱,tid教師編號

3.教師表
teacher(tid,tname)
--tid 教師編號,tname 教師姓名

4.成績表
sc(sid,cid,score)
--sid學(xué)生編號,cid課程編號,score 分數(shù)


二郎仆、建表,插入數(shù)據(jù)

1.學(xué)生表 student

  • mysql建表 / mysql插入數(shù)據(jù):
DROP TABLE IF EXISTS student;
CREATE TABLE student(sid VARCHAR(10),sname VARCHAR(10),sage DATETIME,ssex VARCHAR(10));
INSERT INTO student VALUES('01' , '趙雷' , '1990-01-01' , '男');
INSERT INTO student VALUES('02' , '錢電' , '1990-12-21' , '男');
INSERT INTO student VALUES('03' , '孫風(fēng)' , '1990-12-20' , '男');
INSERT INTO student VALUES('04' , '李云' , '1990-12-06' , '男');
INSERT INTO student VALUES('05' , '周梅' , '1991-12-01' , '女');
INSERT INTO student VALUES('06' , '吳蘭' , '1992-01-01' , '女');
INSERT INTO student VALUES('07' , '鄭竹' , '1989-01-01' , '女');
INSERT INTO student VALUES('08' , '吳八' , '2017-12-20' , '女');
INSERT INTO student VALUES('09' , '張三' , '2017-12-20' , '女');
INSERT INTO student VALUES('10' , '李四' , '2017-12-25' , '女');
INSERT INTO student VALUES('11' , '李四' , '2012-06-06' , '女');
INSERT INTO student VALUES('12' , '趙六' , '2013-06-13' , '女');
INSERT INTO student VALUES('13' , '孫七' , '2014-06-01' , '女');
INSERT INTO student VALUES('14' , '十四' , '2014-06-01' , '男');
  • hive建表 / hvie插入數(shù)據(jù):
DROP TABLE IF EXISTS student;
CREATE TABLE student(
  sid int,
  sname string,
  sage string,
  ssex string
)
row format delimited fields terminated by '\t';

insert into table  student values('01' , 'zhaolei' , '1990-01-01' , 'man'),('02' , 'qiandian' , '1990-12-21' , 'man'),('03' , 'sunfeng' , '1990-12-20' , 'man'),('04' , 'liyun' , '1990-12-06' , 'man'),('05' , 'zhoumei' , '1991-12-01' , 'female'),('06' , 'wulan' , '1992-01-01' , 'female'),('07' , 'zhenzhu' , '1989-01-01' , 'female'),('08' , 'wuba' , '1989-01-01' , 'female'),('09' , 'zhangsan' , '2017-12-20' , 'female'),('10' , 'lisi' , '2017-12-25' , 'female'),('11' , 'lisi' , '2012-06-06' , 'female'),('12' , 'zhaoliu' , '2013-06-13' , 'female'),('13' , 'sunqi' , '2014-06-01' , 'female'),('14' , 'shisi' , '2014-06-01' , 'man');

2.科目表 course

  • mysql建表 / mysql插入數(shù)據(jù):
CREATE TABLE course
(
    cid   VARCHAR(10),
    cname VARCHAR(10),
    tid   VARCHAR(10)
);

INSERT INTO course VALUES('01' , '語文' , '02');
INSERT INTO course VALUES('02' , '數(shù)學(xué)' , '01');
INSERT INTO course VALUES('03' , '英語' , '03');
  • hive建表 / hvie插入數(shù)據(jù):
create table course(
  cid int,
  cname string,
  tid int
)
row format delimited fields terminated by '\t';

INSERT INTO table course VALUES('01' , 'chinise' , '02');
INSERT INTO table course VALUES('02' , 'math' , '01');
INSERT INTO table course VALUES('03' , 'english' , '03');

上面這種方式插入有點慢,用下面這種方式

insert into table course values('01' , 'chinise' , '02'),('02' , 'math' , '01'),('03' , 'english' , '03');

3.教師表 teacher

  • mysql建表 / mysql插入數(shù)據(jù):
CREATE TABLE teacher(tid VARCHAR(10),tname VARCHAR(10));
INSERT INTO teacher VALUES('01' , '張三');
INSERT INTO teacher VALUES('02' , '李四');
INSERT INTO teacher VALUES('03' , '王五');
  • hive建表 / hvie插入數(shù)據(jù):
  create table teacher(
  tid int,
  tname string
)
row format delimited fields terminated by '\t';
insert into table Teacher values('01' , 'zhangsan'),('02' , 'lisi'),('03' , 'wangwu');

4.成績表 sc

  • mysql建表 / mysql插入數(shù)據(jù):
CREATE TABLE sc(sid VARCHAR(10),cid VARCHAR(10),score DECIMAL(18,1));
INSERT INTO sc VALUES('01' , '01' , 80);
INSERT INTO sc VALUES('01' , '02' , 90);
INSERT INTO sc VALUES('01' , '03' , 99);
INSERT INTO sc VALUES('02' , '01' , 70);
INSERT INTO sc VALUES('02' , '02' , 60);
INSERT INTO sc VALUES('02' , '03' , 80);
INSERT INTO sc VALUES('03' , '01' , 80);
INSERT INTO sc VALUES('03' , '02' , 80);
INSERT INTO sc VALUES('03' , '03' , 80);
INSERT INTO sc VALUES('04' , '01' , 50);
INSERT INTO sc VALUES('04' , '02' , 30);
INSERT INTO sc VALUES('04' , '03' , 20);
INSERT INTO sc VALUES('05' , '01' , 76);
INSERT INTO sc VALUES('05' , '02' , 87);
INSERT INTO sc VALUES('06' , '01' , 31);
INSERT INTO sc VALUES('06' , '03' , 69);
INSERT INTO sc VALUES('07' , '02' , 90);
INSERT INTO sc VALUES('07' , '03' , 98);
INSERT INTO sc VALUES('08' , '01' , 65);
INSERT INTO sc VALUES('08' , '02' , null);
INSERT INTO sc VALUES('08' , '03' , 98);
  • hive建表 / hvie插入數(shù)據(jù):
create table sc(
  sid int,
  cid int,
  score int
)
row format delimited fields terminated by '\t';
insert into table  sc values('01' , '01' , 80),('01' , '02' , 90),('01' , '03' , 99),('02' , '01' , 70),('02' , '02' , 60),('02' , '03' , 80),('03' , '01' , 80),('03' , '02' , 80),('03' , '03' , 80),('04' , '01' , 50),('04' , '02' , 30),('04' , '03' , 20),('05' , '01' , 76),('05' , '02' , 87),('06' , '01' , 31),('06' , '03' , 69),('07' , '02' , 90),('07' , '03' , 98),('08' , '01' , 65),('08' , '02' , null),('08' , '03' , 98);

三兜蠕、題目

1.查詢" 01 "課程比" 02 "課程成績高的學(xué)生的信息及課程分數(shù)

2.查詢同時存在" 01 "課程和" 02 "課程的成績情況

3.查詢存在" 01 "課程但可能不存在" 02 "課程的成績情況(不存在時顯示為 null )

4.查詢不存在" 01 "課程但存在" 02 "課程的成績情況

5.查詢平均成績大于等于 60 分的同學(xué)的學(xué)生編號和學(xué)生姓名和平均成績

6.查詢在 SC 表存在成績的學(xué)生信息

7.查詢所有同學(xué)的學(xué)生編號扰肌、學(xué)生姓名、選課總數(shù)熊杨、所有課程的總成績(沒成績的顯示為 null )

8.查有成績的學(xué)生信息

9.查詢「李」姓老師的數(shù)量

10.查詢學(xué)過「張三」老師授課的同學(xué)的信息

11.查詢沒有學(xué)全所有課程的同學(xué)的信息

12.查詢至少有一門課與學(xué)號為" 01 "的同學(xué)所學(xué)相同的同學(xué)的信息

13.查詢和" 01 "號的同學(xué)學(xué)習(xí)的課程 完全相同的其他同學(xué)的信息

14.查詢沒學(xué)過"張三"老師講授的任一門課程的學(xué)生姓名

15.查詢兩門及其以上不及格課程的同學(xué)的學(xué)號曙旭,姓名及其平均成績

16.檢索" 01 "課程分數(shù)小于 60,按分數(shù)降序排列的學(xué)生信息

17.按平均成績從高到低顯示所有學(xué)生的所有課程的成績以及平均成績

18.查詢各科成績最高分晶府、最低分和平均分:

19.以如下形式顯示:課程 ID桂躏,課程 name,最高分川陆,最低分剂习,平均分,及格率较沪,中等率路鹰,優(yōu)良率粗仓,優(yōu)秀率

20.及格為>=60,中等為:70-80览爵,優(yōu)良為:80-90彪腔,優(yōu)秀為:>=90

21.要求輸出課程號和選修人數(shù)不恭,查詢結(jié)果按人數(shù)降序排列缠诅,若人數(shù)相同宿礁,按課程號升序排列

22.按各科成績進行排序,并顯示排名茬射, Score 重復(fù)時保留名次空缺

23.按各科成績進行排序鹦蠕,并顯示排名, Score 重復(fù)時合并名次

24.查詢學(xué)生的總成績躲株,并進行排名片部,總分重復(fù)時保留名次空缺

25.查詢學(xué)生的總成績镣衡,并進行排名霜定,總分重復(fù)時不保留名次空缺

26.統(tǒng)計各科成績各分數(shù)段人數(shù):課程編號,課程名稱廊鸥,[100-85]望浩,[85-70],[70-60]惰说,[60-0] 及所占百分比

27.查詢各科成績前三名的記錄

28.查詢每門課程被選修的學(xué)生數(shù)

29.查詢出只選修兩門課程的學(xué)生學(xué)號和姓名

30.查詢男生磨德、女生人數(shù)

31.查詢名字中含有「風(fēng)」字的學(xué)生信息

32.查詢同名同性學(xué)生名單,并統(tǒng)計同名人數(shù)

33.查詢 1990 年出生的學(xué)生名單

34.查詢每門課程的平均成績,結(jié)果按平均成績降序排列典挑,平均成績相同時酥宴,按課程編號升序排列

35.查詢平均成績大于等于 85 的所有學(xué)生的學(xué)號、姓名和平均成績

36.查詢課程名稱為「數(shù)學(xué)」您觉,且分數(shù)低于 60 的學(xué)生姓名和分數(shù)

37.查詢所有學(xué)生的課程及分數(shù)情況(存在學(xué)生沒成績拙寡,沒選課的情況)

38.查詢?nèi)魏我婚T課程成績在 70 分以上的姓名、課程名稱和分數(shù)

39.查詢不及格的課程

40.查詢課程編號為 01 且課程成績在 80 分以上的學(xué)生的學(xué)號和姓名

41.求每門課程的學(xué)生人數(shù)

42.成績不重復(fù)琳水,查詢選修「張三」老師所授課程的學(xué)生中肆糕,成績最高的學(xué)生信息及其成績

43.成績有重復(fù)的情況下,查詢選修「張三」老師所授課程的學(xué)生中在孝,成績最高的學(xué)生信息及其成績

44.查詢不同課程成績相同的學(xué)生的學(xué)生編號诚啃、課程編號、學(xué)生成績

45.查詢每門功成績最好的前兩名

46.統(tǒng)計每門課程的學(xué)生選修人數(shù)(超過 5 人的課程才統(tǒng)計)私沮。

47.檢索至少選修兩門課程的學(xué)生學(xué)號

48.查詢選修了全部課程的學(xué)生信息

49.查詢各學(xué)生的年齡始赎,只按年份來算

50.按照出生日期來算,當(dāng)前月日 < 出生年月的月日則仔燕,年齡減一

51.查詢本周過生日的學(xué)生

52.查詢下周過生日的學(xué)生

53.查詢本月過生日的學(xué)生

54.查詢下月過生日的學(xué)生


四极阅、答案

答案不固定,各位如果有好的優(yōu)化方法可以在評論區(qū)貼上涨享。

1.查詢" 01 "課程比" 02 "課程成績高的學(xué)生的信息及課程分數(shù)

第一種寫法:

select a1.sid,
       a1.sname,
       a1.sage,
       a1.ssex,
       a2.score1,
       a2.score2
from student a1
         right join (
    select t1.sid,
           score1,
           score2
    from (select sid, score as score1 from sc where cid = '01') t1,
         (select sid, score as score2 from sc where cid = '02') t2
    where t1.sid = t2.sid
      and t1.score1 > t2.score2
)a2
on a1.sid=a2.sid
;

去看一下MySql查詢select from 兩個表與left join on的區(qū)別
https://blog.csdn.net/weixin_33738555/article/details/91689609

第二種寫法

select a1.sid,
       a1.sname,
       a1.sage,
       a1.ssex,
       a2.score1,
       a2.score2
from student a1
         right join (
    select t1.sid,
           t1.score1 as score1,
           t2.score2 as score2
    from (
             select sid,
                    score as score1
             from sc
             where cid = '01'
         ) t1
             left join (
        select sid,
               score as score2
        from sc
        where cid = '02'
    ) t2
                       on t1.sid = t2.sid
    where t1.score1 > t2.score2
) a2
                    on a1.sid = a2.sid
;

2.查詢同時存在" 01 "課程和" 02 "課程的成績情況
select t1.sid,
       t1.score1,
       t2.score2
from
(select sid,score as score1 from sc where cid = '01')t1,
(select sid,score as score2 from sc where cid = '02')t2
where t1.sid = t2.sid;

同時存在即:\color{red}{內(nèi)連接}

select t1.sid,
       t1.score1,
       t2.score2
from
(select sid,score as score1 from sc where cid = '01')t1
join 
(select sid,score as score2 from sc where cid = '02')t2
where t1.sid = t2.sid;
3.查詢存在" 01 "課程但可能不存在" 02 "課程的成績情況(不存在時顯示為 null )

即:\color{red}{左連接}

select t1.sid,
       t1.cid,
       t1.score
from sc t1
where t1.sid not in(
    select sid from sc where cid = '02'
    )
and t1.cid = '01'
;

select t1.sid,
       t1.score1,
       t2.score2
from
(select sid,score as score1 from sc where cid = '01')t1
left join
(select sid,score as score2 from sc where cid = '02')t2
where t1.sid = t2.sid;
4.查詢存在" 01 “課程但不存在” 02 "課程的成績情況
select *
from (select sid, score as score1 from sc where cid = '01') t1
         left join
         (select sid, score as score2 from sc where cid = '02') t2
         on t1.sid = t2.sid
where t2.sid is null;
5.查詢平均成績大于等于 60 分的同學(xué)的學(xué)生編號和學(xué)生姓名和平均成績

mysql 寫法:

select t1.sid,
       a1.sname,
       t1.avg_score
from student a1
         right join (
    select sid,
           sum(score) / count(sid) as avg_score
    from sc
    group by sid
    having avg_score > 60
) t1
                    on a1.sid = t1.sid;

hive似乎無法使用having筋搏,一直報錯,有待考證

select t2.sid,
       a1.sname,
       t2.avg_score
from student a1
         right join (
    select t1.sid,
           avg_score
    from (
             select sid,
                    sum(score) / count(sid) as avg_score
             from sc
             group by sid
         ) t1
    where t1.avg_score > 60.0
) t2
                    on a1.sid = t2.sid;

6.查詢在 SC 表存在成績的學(xué)生信息
select distinct (a1.sid),
                a2.sname,
                a2.sage,
                a2.ssex
from sc a1
         left join student a2 on a1.sid = a2.sid;

7.查詢所有同學(xué)的學(xué)生編號厕隧、學(xué)生姓名奔脐、選課總數(shù)、所有課程的總成績(沒成績的顯示為 null )
select a1.sid,
       a1.sname,
       a2.c_cnt,
       a2.s_cnt
from student a1
         left join (
    select t1.sid,
           count(t1.cid) as c_cnt,
           sum(score)    as s_cnt
    from sc t1
    group by t1.sid
) a2
                   on a1.sid = a2.sid;

思考:

--笛卡爾積
select a1.sid, a1.sname, a1.sage, a1.ssex,
       a2.cnt,a2.snt
from student a1,
     (select t1.sid, count(t1.cid) as cnt, sum(score) snt from sc t1 group by t1.sid) a2;

--join
select a1.sid, a1.sname, a1.sage, a1.ssex,
       a2.cnt,a2.snt
from student a1,
     (select t1.sid, count(t1.cid) as cnt, sum(score) snt from sc t1 group by t1.sid) a2
where a1.sid = a2.sid;

--left join
select a1.sid,
       a1.sname,
       a2.c_cnt,
       a2.s_cnt
from student a1
         left join (
    select t1.sid,
           count(t1.cid) as c_cnt,
           sum(score)    as s_cnt
    from sc t1
    group by t1.sid
) a2
                   on a1.sid = a2.sid;

8.查有成績的學(xué)生信息

這一題涉及到in和exists的用法吁讨,在這種小表中髓迎,兩種方法的效率都差不多,但是請參考SQL查詢中in和exists的區(qū)別分析
當(dāng)表2的記錄數(shù)量非常大的時候建丧,選用exists比in要高效很多.
EXISTS用于檢查子查詢是否至少會返回一行數(shù)據(jù)排龄,該子查詢實際上并不返回任何數(shù)據(jù),而是返回值True或False.
結(jié)論:IN()適合B表比A表數(shù)據(jù)小的情況
結(jié)論:EXISTS()適合B表比A表數(shù)據(jù)大的情況

--8.1 join
select a1.*
from student a1
          join (
    select distinct (t1.sid) as sid
    from sc t1
) a2
                   on a1.sid = a2.sid;

-- 8.2 exists
select *
from student
where exists (select sc.sid from sc where student.sid = sc.sid);

-- 8.3 in
select *
from student
where student.sid in (select distinct (sid) from sc);

9.查詢「李」姓老師的數(shù)量

模糊查詢:\color{red}{like}

select count(*)
from teacher a1
where a1.tname like 'li%'
10.查詢學(xué)過「張三」老師授課的同學(xué)的信息
select t4.*
from student t4
         right join (
    select t3.sid
    from sc t3
             right join (
        select t2.cid
        from course t2
                 right join (
            select t1.tid
            from teacher t1
            where t1.tname = 'zhangsan'
        ) a1
                            on t2.tid = a1.tid
    ) a2
                        on t3.cid = a2.cid
) a3
                    on t4.sid = a3.sid;

寫法2:

select *
from student a1,sc a2,teacher a3,course a4
where a1.sid = a2.sid
and a2.cid = a4.cid
and a4.tid = a3.tid
and a3.tname = 'zhangsan';
11.查詢沒有學(xué)全所有課程的同學(xué)的信息
  • mysql寫法
select t3.*
from student t3
         right join (
    select t2.sid,
           count(t2.cid) as cnt
    from sc t2
    group by t2.sid
    having cnt < (
        select count(distinct (t1.cid))
        from course t1
    )
)a1
on t3.sid = a1.sid
;

  • hive 寫法
一直報錯...
12.查詢至少有一門課與學(xué)號為" 01 "的同學(xué)所學(xué)相同的同學(xué)的信息
select t3.*
from student t3
         right join (
    select distinct t2.sid
    from sc t2
    where t2.cid in (
        select t1.cid
        from sc t1
        where t1.sid = '01'
    )
) a1
on t3.sid = a1.sid;

13.查詢和" 01 "號的同學(xué)學(xué)習(xí)的課程 完全相同的其他同學(xué)的信息

思路:
1)查出"01"號學(xué)生的課程數(shù)目
2)查出"01"號學(xué)生的課程內(nèi)容
3)查出課程在"01"學(xué)生所學(xué)的課程內(nèi)容中并且課程數(shù)目和"01"學(xué)生所學(xué)課程數(shù)目相等的學(xué)生
mysql寫法:

select t4.*
from student t4
         right join (
    select a1.sid
    from (
             select t3.sid as sid,
                    t3.cid as cid
             from sc t3
             where t3.cid in (
                 select t2.cid
                 from sc t2
                 where t2.sid = '01'
             )
         ) a1
    group by sid
    having count(sid) = (select count(distinct t1.cid)
                         from sc t1
                         where t1.sid = '01')
) a2
                    on t4.sid = a2.sid
;
14.查詢沒學(xué)過"張三"老師講授的任一門課程的學(xué)生姓名
--mysql 寫法
select distinct t4.sname
from student t4
         right join (
    select t3.sid

    from sc t3
    where t3.cid not in (
        select t2.cid
        from course t2
        where tid in (
            select t1.tid
            from teacher t1
            where t1.tname = 'zhangsan'
        )
    )
)a1
on t4.sid = a1.sid;

15.查詢兩門及其以上不及格課程的同學(xué)的學(xué)號翎朱,姓名及其平均成績
select a1.sid,
       t2.sname
from student t2
         right join (
    select t1.sid,
           sum(t1.score) / count(t1.sid)
    from sc t1
    where t1.score < 60
    group by t1.sid
    having count(t1.sid) > 2
) a1
                    on t2.sid = a1.sid;

16.檢索" 01 "課程分數(shù)小于 60橄维,按分數(shù)降序排列的學(xué)生信息
-- 寫法1
select t2.*,
       a1.score
from student t2
         right join (
    select t1.sid,
           t1.score as score
    from sc t1
    where t1.cid = '01'
      and t1.score < 60
)a1
on a1.sid = t2.sid
order by a1.score desc;

--寫法2
select t1.*,
       t2.score
from student t1
         right join sc t2
                    on t1.sid = t2.sid
where t2.cid = '01'
  and t2.score < 60
order by t2.score desc;
17.按平均成績從高到低顯示所有學(xué)生的所有課程的成績以及平均成績
-- mysql /hive 寫法
select a1.sid1,
       a1.score,
       a2.avg_score
from
(select t1.sid as sid1,t1.score as score from sc t1)a1,
(select t2.sid as sid2,avg(t2.score) as avg_score from sc t2 group by t2.sid) a2
where a1.sid1 = a2.sid2
order by a2.avg_score desc
;

--hive 寫法(開窗口)
select t1.sid,
       t1.score,
       avg(score) over (partition by t1.sid) as avg_score
from sc t1
order by avg_score desc
;
18.查詢各科成績最高分、最低分和平均分:
select t1.cid,
       max(t1.score),
       min(t1.score),
       avg(t1.score)
from sc t1
group by t1.cid;
19.以如下形式顯示:課程 ID拴曲,課程 name争舞,最高分,最低分澈灼,平均分竞川,及格率店溢,中等率,優(yōu)良率委乌,優(yōu)秀率床牧;及格為>=60,中等為:70-80遭贸,優(yōu)良為:80-90叠赦,優(yōu)秀為:>=90;要求輸出課程號和選修人數(shù)革砸,查詢結(jié)果按人數(shù)降序排列除秀,若人數(shù)相同,按課程號升序排列
select t1.cid,
       max(t1.score),
       min(t1.score),
       avg(t1.score),
       count(*) as cnt,
       sum(case when t1.score >= 60 then 1 else 0 end ) / count(*) ,
       sum(case when t1.score > 60 and t1.score <= 70 then 1 else 0 end ) / count(*),
       sum(case when t1.score > 70 and t1.score <= 80 then 1 else 0 end ) / count(*),
       sum(case when t1.score > 80 and t1.score <= 90 then 1 else 0 end ) / count(*),
       sum(case when t1.score >= 90 then 1 else 0 end ) / count(*)
from sc t1
group by t1.cid
order by cnt desc , t1.cid
;
20.按各科成績進行排序算利,并顯示排名册踩, score 重復(fù)時,合并(即排名:1,1,3....)

思路: 自交效拭,sc t1自己left join 自己t2暂吉,查詢t2表中在t1表當(dāng)前分數(shù)的高還有幾個

  • mysql
--mysql
--思路: sc t1自己left join 自己t2,查詢t2表中在t1表當(dāng)前分數(shù)的高還有幾個
select t1.cid,t1.sid,t1.score,count(t2.score) + 1 as rank, t2.cid,t2.sid,t2.score
from sc t1
left join sc t2
on t1.score < t2.score and t1.cid = t2.cid
group by t1.cid, t1.sid, t1.score
order by t1.cid, rank asc
;

-- 或者
select a.sid,a.cid,a.score,count(b.cid)+1 as rank from sc a 
left join sc b on a.cid = b.cid and a.score<b.score
group by a.cid, a.sid
order by a.cid, rank asc;
  • hive
-- hive (rank排序打標記)
-- 排序相同時會重復(fù)缎患,總數(shù)不變 1,1,3...
select t1.cid,t1.sid,t1.score,
       rank() over (partition by t1.cid order by t1.score desc) as rank
from sc t1;

-- 排序相同時會重復(fù)慕的,總數(shù)變少 1,1,3...
select t1.cid,t1.sid,t1.score,
       dense_rank() over (partition by t1.cid order by t1.score desc) as rank
from sc t1;

-- 會根據(jù)順序計算, 1,2,3...
select t1.cid,t1.sid,t1.score,
       row_number() over (partition by t1.cid order by t1.score desc) as rank
from sc t1;
21.按各科成績進行排序,并顯示排名挤渔, score 重復(fù)時肮街,不合并(即排名:1,2,3...)
  • mysql
    思路,用order by a,b 就能夠?qū)id字段進行分組判导,再對score進行排序嫉父。用兩個參數(shù),第一個字段記錄上一個cid,第二個字段用來標記當(dāng)前行cid是否為上一個cid眼刃,如果是就自加绕辖,不是就賦值為1。
set @rankid =0;
set @couse_id =0;
select a.*,
@rankid := if(@couse_id = cid,@rankid + 1, 1) rankid,
@couse_id := a.cid couse_id
from sc a
order by cid,score desc;

可參考:https://blog.csdn.net/qq_41902618/article/details/108514316

  • hive
-- 會根據(jù)順序計算, 1,2,3...
select t1.cid,t1.sid,t1.score,
       row_number() over (partition by t1.cid order by t1.score desc) as rank
from sc t1;
22.查詢學(xué)生的總成績擂红,并進行排名仪际,總分重復(fù)時,不合并(即排名:1,2,3...)
  • mysql
    mysql 變量:\color{red}{變量}

mysql寫法1

set @crank = 0;
select a1.sid,
       a1.total_score,
       @crank := @crank + 1 as rank
from (
         select t1.sid,
                sum(t1.score) as total_score
         from sc t1
         group by t1.sid
         order by total_score desc
     ) a1
;
23.查詢學(xué)生的總成績,并進行排名昵骤,總分重復(fù)時,合并(即排名:1,1,3....)
  • mysql
    思路:通過自交的方式树碱,求temp3中在temp2中大于當(dāng)前分數(shù)的個數(shù)
DROP TABLE IF EXISTS temp2;
create temporary table temp2
select t1.sid,
       sum(t1.score) as total_score
from sc t1
group by t1.sid;

DROP TABLE IF EXISTS temp3;
create temporary table temp3
select t1.sid,
       sum(t1.score) as total_score
from sc t1
group by t1.sid;

select t2.sid,
       t2.total_score,
       count(t3.total_score) + 1 rank
from temp2 t2 left join temp3 t3
on t2.total_score < t3.total_score
group by t2.sid, t2.total_score
order by rank asc;
  • hive
--hive
select a1.sid,
       a1.total_score,
       rank() over (order by a1.total_score desc)
from (
         select t1.sid,
                sum(t1.score) as total_score
         from sc t1
         group by t1.sid
     ) a1
;

24.統(tǒng)計各科成績各分數(shù)段人數(shù):課程編號,課程名稱涉茧,[100-85]赴恨,[85-70]疹娶,[70-60]伴栓,[60-0] 及所占百分比
select t2.cname,
       a1.*
from course t2
         right join (
    select t1.cid                                                                         as cid,
           sum(case when t1.score <= 60 then 1 else 0 end)                                as p_per1,
           sum(case when t1.score >= 60 and t1.score <= 70 then 1 else 0 end)             as p_per2,
           sum(case when t1.score >= 70 and t1.score <= 85 then 1 else 0 end)             as p_per3,
           sum(case when t1.score >= 85 and t1.score <= 100 then 1 else 0 end)            as p_per4,
           sum(case when t1.score <= 60 then 1 else 0 end) / count(*)                     as c_per1,
           sum(case when t1.score >= 60 and t1.score <= 70 then 1 else 0 end) / count(*)  as c_per2,
           sum(case when t1.score >= 70 and t1.score <= 85 then 1 else 0 end) / count(*)  as c_per3,
           sum(case when t1.score >= 85 and t1.score <= 100 then 1 else 0 end) / count(*) as c_per4
    from sc t1
    group by t1.cid
) a1
                    on t2.cid = a1.cid
;

25.查詢各科成績前三名的記錄
  • mysql
    寫法1:計算比自己分數(shù)大的記錄有幾條,如果小于3 就select,因為對前三名來說不會有3個及以上的分數(shù)比自己大了钳垮,最后再對所有select到的結(jié)果按照分數(shù)和課程編號排名即可惑淳。
select *
from sc t1
where (
          select count(*)
          from sc t2
          where t1.cid = t2.cid
            and t1.score < t2.score
      ) < 3
            and t1.score is not  null
order by t1.cid, t1.score desc
;

寫法2:自身左交, rank小于3,就是前3

select a.sid,a.cid,a.score,count(b.cid)+1 as rank from sc a 
left join sc b on a.cid = b.cid and a.score<b.score
group by a.cid, a.sid
having rank <= 3
order by a.cid, rank asc;

寫法3:

set @rankid =0;
set @couse_id =0;

select a1.*
from (
         select a.*,
                @rankid := if(@couse_id = cid,@rankid + 1, 1) rankid,
                @couse_id := a.cid couse_id
         from sc a
         order by cid, score desc
     )a1
where a1.rankid <= 3
;
  • hive
select *
from (
         select t1.cid,
                t1.sid,
                t1.score,
                row_number() over (partition by t1.cid order by t1.score desc) as rank
         from sc t1
     ) a1
where a1.rank <= 3;
26.查詢每門課程被選修的學(xué)生數(shù)
select t1.cid,
       count(t1.sid)
from sc t1
group by t1.cid;

27.查詢出只選修兩門課程的學(xué)生學(xué)號和姓名
select a1.sid,
       t2.sname
from student t2
         right join (
    select t1.sid,
           count(t1.cid) as cnt
    from sc t1
    group by t1.sid
    having cnt = 2
)a1
on t2.sid = a1.sid;

28.查詢男生饺窿、女生人數(shù)
select t1.ssex,
       count(t1.sid) as cnt
from student t1
group by t1.ssex;
29.查詢名字中含有「風(fēng)」字的學(xué)生信息
select *
from student t1
where t1.sname like '%風(fēng)%'
30.查詢同名同姓學(xué)生名單歧焦,并統(tǒng)計同名人數(shù)
select t1.sname,
       count(sid) cnt
from student t1
group by t1.sname
having cnt >= 2;
31.查詢 1990 年出生的學(xué)生名單
select *
from student
where YEAR(student.sage)=1990;
32.查詢每門課程的平均成績,結(jié)果按平均成績降序排列肚医,平均成績相同時绢馍,按課程編號升序排列
select t1.cid,
       avg(t1.score) avg_score
from sc t1
group by t1.cid
order by avg_score desc,t1.cid desc; 

-- 將排名列出
set @crank = 0;
select a1.cid,
       a1.avg_score,
       @crank := @crank + 1 as rank
from (
         select t1.cid,
                avg(t1.score) avg_score
         from sc t1
         group by t1.cid
         order by avg_score, t1.cid
     ) a1;

33.查詢平均成績大于等于 85 的所有學(xué)生的學(xué)號、姓名和平均成績
select t2.sid,
       t2.sname,
       a1.avg_score
from student t2
         right join (
    select t1.sid,
           avg(t1.score) avg_score
    from sc t1
    group by t1.sid
    having avg_score >= 85
) a1
                    on t2.sid = a1.sid;

34.查詢課程名稱為「數(shù)學(xué)」肠套,且分數(shù)低于 60 的學(xué)生姓名和分數(shù)
select t3.sname,
       a2.score
from student t3
         right join (
    select t2.sid,
           t2.score
    from sc t2
             right join (
        select t1.cid
        from course t1
        where t1.cname = '數(shù)學(xué)'
    ) a1
                        on a1.cid = t2.cid
    where t2.score < 60
) a2
                    on t3.sid = a2.sid;

-- 或者
select student.sname, sc.score from student, sc, course
where student.sid = sc.sid
and course.cid = sc.cid
and course.cname = "數(shù)學(xué)"
and sc.score < 60;

35.查詢所有學(xué)生的課程及分數(shù)情況(存在學(xué)生沒成績舰涌,沒選課的情況)
select student.sname, cid, score from student
left join sc
on student.sid = sc.sid;
36.查詢?nèi)魏我婚T課程成績在 70 分以上的姓名、課程名稱和分數(shù)
select t1.sid,
       t2.sname,
       t3.cname,
       t1.score
from sc t1
left join student t2 on t1.sid = t2.sid
left join course t3 on t1.cid = t3.cid
where t1.score > 70;
37.查詢存在不及格的課程
select t2.*,
       t1.*
from sc t1
         left join course t2 on t1.cid = t2.cid
where t1.score < 60;
38.查詢課程編號為 01 且課程成績在 80 分以上的學(xué)生的學(xué)號和姓名
select t2.sid,
       t2.sname
from sc t1
left join student t2 on t1.sid = t2.sid
where t1.cid='01'
and t1.score >= 80;

39.求每門課程的學(xué)生人數(shù)
select t1.cid,
       count(t1.sid)  as cnt
from sc t1
group by t1.cid;
40.成績不重復(fù)你稚,查詢選修「張三」老師所授課程的學(xué)生中瓷耙,成績最高的學(xué)生信息及其成績
set @crank = 0;
select t4.*
from student t4
         right join (
    select a2.sid
    from (
             select a1.*,
                    @crank := @crank + 1 as rank
             from (
                 select t1.tid,
                 t2.cid,
                 t3.sid,
                 t3.score
                 from teacher t1
                 left join course t2 on t1.tid = t2.tid
                 left join sc t3 on t2.cid = t3.cid
                 where t1.tname = '張三'
                 order by t3.score desc
                 ) a1
         ) a2
    where a2.rank = 1
)a3
on t4.sid = a3.sid;
41.成績有重復(fù)的情況下,查詢選修「張三」老師所授課程的學(xué)生中刁赖,成績最高的學(xué)生信息及其成績

42.查詢不同課程成績相同的學(xué)生的學(xué)生編號搁痛、課程編號、學(xué)生成績

這里用了inner join后會有概念是重復(fù)的記錄:“01 課與 03課”=“03 課與 01 課”宇弛,所以這里取唯一一條可以直接用group by

select  a.cid, a.sid,  a.score from sc as a
inner join 
sc as b
on a.sid = b.sid
and a.cid != b.cid
and a.score = b.score
group by cid, sid;
43.查詢每門功課成績最好的前兩名

同25題

select *
from sc t1
where (
          select count(*)
          from sc t2
          where t1.cid = t2.cid
            and t1.score < t2.score
      ) < 2
            and t1.score is not  null
order by t1.cid, t1.score desc
;

44.統(tǒng)計每門課程的學(xué)生選修人數(shù)(超過 5 人的課程才統(tǒng)計)鸡典。
select t1.cid,
       count(t1.sid) as cnt
from sc t1
group by t1.cid
having cnt > 5;
45.檢索至少選修兩門課程的學(xué)生學(xué)號
select t1.sid,
       count(cid) cnt
from sc t1
group by sid
having cnt >= 2
;
46.查詢選修了全部課程的學(xué)生信息
select t2.*
from student t2
         right join (
    select t1.sid as sid,
           count(cid) as cnt
    from sc t1
    group by sid
    having cnt = (select count(distinct (cid)) from course)

)a1
on t2.sid = a1.sid;

47.查詢各學(xué)生的年齡,只按年份來算
select t1.sid as 學(xué)生編號,
       t1.sname as  學(xué)生姓名,
       TIMESTAMPDIFF(YEAR, t1.sage, CURDATE()) as 學(xué)生年齡
from student t1;
48.按照出生日期來算枪芒,當(dāng)前月日 < 出生年月的月日則轿钠,年齡減一
select t1.sid as 學(xué)生編號,
       t1.sname as  學(xué)生姓名,
       TIMESTAMPDIFF(YEAR, t1.sage, CURDATE()) as 學(xué)生年齡
from student t1;
49.查詢本周過生日的學(xué)生
select *
from student t1
where WEEKOFYEAR(t1.sage)=WEEKOFYEAR(CURDATE());
50.查詢下周過生日的學(xué)生
select *
from student t1
where WEEKOFYEAR(t1.sage)=WEEKOFYEAR(CURDATE())+1;
51.查詢本月過生日的學(xué)生
select *
from student t1
where MONTH(t1.sage)=MONTH(CURDATE());
52.查詢下月過生日的學(xué)生
select *
from student t1
where MONTH(t1.sage)=MONTH(CURDATE())+1;
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市病苗,隨后出現(xiàn)的幾起案子疗垛,更是在濱河造成了極大的恐慌,老刑警劉巖硫朦,帶你破解...
    沈念sama閱讀 221,548評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件贷腕,死亡現(xiàn)場離奇詭異,居然都是意外死亡咬展,警方通過查閱死者的電腦和手機泽裳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來破婆,“玉大人涮总,你說我怎么就攤上這事〉灰ǎ” “怎么了瀑梗?”我有些...
    開封第一講書人閱讀 167,990評論 0 360
  • 文/不壞的土叔 我叫張陵烹笔,是天一觀的道長。 經(jīng)常有香客問我抛丽,道長谤职,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,618評論 1 296
  • 正文 為了忘掉前任亿鲜,我火速辦了婚禮允蜈,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蒿柳。我一直安慰自己饶套,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,618評論 6 397
  • 文/花漫 我一把揭開白布垒探。 她就那樣靜靜地躺著凤跑,像睡著了一般。 火紅的嫁衣襯著肌膚如雪叛复。 梳的紋絲不亂的頭發(fā)上仔引,一...
    開封第一講書人閱讀 52,246評論 1 308
  • 那天,我揣著相機與錄音褐奥,去河邊找鬼咖耘。 笑死,一個胖子當(dāng)著我的面吹牛撬码,可吹牛的內(nèi)容都是我干的儿倒。 我是一名探鬼主播,決...
    沈念sama閱讀 40,819評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼呜笑,長吁一口氣:“原來是場噩夢啊……” “哼夫否!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起叫胁,我...
    開封第一講書人閱讀 39,725評論 0 276
  • 序言:老撾萬榮一對情侶失蹤凰慈,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后驼鹅,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體微谓,經(jīng)...
    沈念sama閱讀 46,268評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,356評論 3 340
  • 正文 我和宋清朗相戀三年输钩,在試婚紗的時候發(fā)現(xiàn)自己被綠了豺型。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,488評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡买乃,死狀恐怖姻氨,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情剪验,我是刑警寧澤肴焊,帶...
    沈念sama閱讀 36,181評論 5 350
  • 正文 年R本政府宣布前联,位于F島的核電站,受9級特大地震影響抖韩,放射性物質(zhì)發(fā)生泄漏蛀恩。R本人自食惡果不足惜疫铜,卻給世界環(huán)境...
    茶點故事閱讀 41,862評論 3 333
  • 文/蒙蒙 一茂浮、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧壳咕,春花似錦席揽、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,331評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至竟稳,卻和暖如春属桦,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背他爸。 一陣腳步聲響...
    開封第一講書人閱讀 33,445評論 1 272
  • 我被黑心中介騙來泰國打工聂宾, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人诊笤。 一個月前我還...
    沈念sama閱讀 48,897評論 3 376
  • 正文 我出身青樓系谐,卻偏偏與公主長得像,于是被迫代替她去往敵國和親讨跟。 傳聞我的和親對象是個殘疾皇子纪他,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,500評論 2 359

推薦閱讀更多精彩內(nèi)容

  • 表名和字段 --插入學(xué)生表測試數(shù)據(jù)insert into Student values('01' , '趙雷' ,...
    C1R2閱讀 5,332評論 0 1
  • 一個題目涉及到的50個Sql語句--(下面表的結(jié)構(gòu)以給出,自己在數(shù)據(jù)庫中建立表.并且添加相應(yīng)的數(shù)據(jù),數(shù)據(jù)要全面些....
    Help_II閱讀 328評論 0 0
  • 關(guān)于學(xué)生,課程晾匠,成績茶袒,教師表 student(學(xué)號#,姓名,性別,年齡) course(課程號#,課程名凉馆,教師號#...
    訫菲閱讀 20,766評論 2 7
  • 建表create table student(s_id string,s_name string,s_birth ...
    VincentLeon閱讀 152評論 0 0
  • 表情是什么弹谁,我認為表情就是表現(xiàn)出來的情緒。表情可以傳達很多信息句喜。高興了當(dāng)然就笑了预愤,難過就哭了。兩者是相互影響密不可...
    Persistenc_6aea閱讀 125,303評論 2 7