zoukankan      html  css  js  c++  java
  • 45道SQL数据题详细超基础解析

    45道SQL题可以说是SQL学习里面最为经典题目,吃透它可以说,对于SQL语句的使用会有很大的提升和感悟。

    这里我不仅将题目和答案总结到一起,同时把涉及的基础知识也会一点点结合到一块,也会把一些查阅到的优秀讲解文章链接到这里,节约读者的查阅时间。

    目前博主也是刚开始学,所以有什么问题,可以积极指出。

    1.查询语句不同元素(where、jion、limit、group by、having等等)执行先后顺序?
    1.查询中用到的关键词主要包含六个,并且他们的顺序依次为 select--from--where--group by--having--order by
    其中select和from是必须的,其他关键词是可选的,这六个关键词的执行顺序 与sql语句的书写顺序并不是一样的,而是按照下面的顺序来执行

    from:需要从哪个数据表检索数据

    where:过滤表中数据的条件

    group by:如何将上面过滤出的数据分组

    having:对上面已经分组的数据进行过滤的条件

    select:查看结果集中的哪个列,或列的计算结果

    order by :按照什么样的顺序来查看返回的数据

    2.from后面的表关联,是自右向左解析 而where条件的解析顺序是自下而上的。
    也就是说,在写SQL语句的时候,尽量把数据量小的表放在最右边来进行关联(用小表去匹配大表),而把能筛选出小量数据的条件放在where语句的最左边 (用小表去匹配大表)

    图片中显示的A和B表示的是A或B中的KEY的关系。
    比如

    select <select_list>
    from tableA A inner join tableB B
    on A.key = B.key
    表示只取A和B中,两部分的key中相同的部分,其他的都不要。
    

    创建表:

    //创建学生表,前面的s表示学生,相应的标签前面加t表示老师
    //CREATE TABLE [表名]创建
    //[列名] [格式] [设定条件1] [设定条件2] [设定条件3]....,
    CREATE TABLE students
    (
    
    sno VARCHAR(3) NOT NULL,
     
    sname VARCHAR(4) NOT NULL,
     
    ssex VARCHAR(2) NOT NULL,
     
    sbirthday DATETIME,
     
    class VARCHAR(5))
     
     
     //创建课程表,con表示课程名,sno表示学号,degree表示分数
    CREATE TABLE courses
     
    (cno VARCHAR(5) NOT NULL,
     
    cname VARCHAR(10) NOT NULL,
     
    tno VARCHAR(10) NOT NULL)
     
     
     //创建分数表
    CREATE TABLE scores
     
    (sno VARCHAR(3) NOT NULL,
     
    cno VARCHAR(5) NOT NULL,
     
    degree NUMERIC(10, 1) NOT NULL)
     
     
     //创建教师表
    CREATE TABLE teachers
     
    (tno VARCHAR(3) NOT NULL,
     
    tname VARCHAR(4) NOT NULL, tsex VARCHAR(2) NOT NULL,
     
    tbirthday DATETIME NOT NULL, prof VARCHAR(6),
     
    depart VARCHAR(10) NOT NULL)
    




    插入示范数据

    //往学生表中插入数据
    //INSERT INTO [表名]([列1],[列2],[列3],[列4]...) VALUES (数值1,数值2,数值3,数值4...);
    
    INSERT INTO STUDENTS (SNO,SNAME,SSEX,SBIRTHDAY,CLASS) VALUES (108 ,'曾华' ,'男' ,'1977-09-01',95033);
     
    INSERT INTO STUDENTS (SNO,SNAME,SSEX,SBIRTHDAY,CLASS) VALUES (105 ,'匡明' ,'男' ,'1975-10-02',95031);
     
    INSERT INTO STUDENTS (SNO,SNAME,SSEX,SBIRTHDAY,CLASS) VALUES (107 ,'王丽' ,'女' ,'1976-01-23',95033);
     
    INSERT INTO STUDENTS (SNO,SNAME,SSEX,SBIRTHDAY,CLASS) VALUES (101 ,'李军' ,'男' ,'1976-02-20',95033);
     
    INSERT INTO STUDENTS (SNO,SNAME,SSEX,SBIRTHDAY,CLASS) VALUES (109 ,'王芳' ,'女' ,'1975-02-10',95031);
     
    INSERT INTO STUDENTS (SNO,SNAME,SSEX,SBIRTHDAY,CLASS) VALUES (103 ,'陆君' ,'男' ,'1974-06-03',95031);
     
     
     //往课程表中插入数据
    INSERT INTO COURSES(CNO,CNAME,TNO)VALUES ('3-105' ,'计算机导论',825);
     
    INSERT INTO COURSES(CNO,CNAME,TNO)VALUES ('3-245' ,'操作系统' ,804);
     
    INSERT INTO COURSES(CNO,CNAME,TNO)VALUES ('6-166' ,'数据电路' ,856);
     
    INSERT INTO COURSES(CNO,CNAME,TNO)VALUES ('9-888' ,'高等数学' ,100);
    
    
    //往分数表添加分数
     
    INSERT INTO SCORES(SNO,CNO,DEGREE)VALUES (103,'3-245',86);
     
    INSERT INTO SCORES(SNO,CNO,DEGREE)VALUES (105,'3-245',75);
     
    INSERT INTO SCORES(SNO,CNO,DEGREE)VALUES (109,'3-245',68);
     
    INSERT INTO SCORES(SNO,CNO,DEGREE)VALUES (103,'3-105',92);
     
    INSERT INTO SCORES(SNO,CNO,DEGREE)VALUES (105,'3-105',88);
     
    INSERT INTO SCORES(SNO,CNO,DEGREE)VALUES (109,'3-105',76);
     
    INSERT INTO SCORES(SNO,CNO,DEGREE)VALUES (101,'3-105',64);
     
    INSERT INTO SCORES(SNO,CNO,DEGREE)VALUES (107,'3-105',91);
     
    INSERT INTO SCORES(SNO,CNO,DEGREE)VALUES (108,'3-105',78);
     
    INSERT INTO SCORES(SNO,CNO,DEGREE)VALUES (101,'6-166',85);
     
    INSERT INTO SCORES(SNO,CNO,DEGREE)VALUES (107,'6-106',79);
     
    INSERT INTO SCORES(SNO,CNO,DEGREE)VALUES (108,'6-166',81);
    
    //往教师表里面插入数据
     
    INSERT INTO TEACHERS(TNO,TNAME,TSEX,TBIRTHDAY,PROF,DEPART) VALUES (804,'李诚','男','1958-12-02','副教授','计算机系');
     
    INSERT INTO TEACHERS(TNO,TNAME,TSEX,TBIRTHDAY,PROF,DEPART) VALUES (856,'张旭','男','1969-03-12','讲师','电子工程系');
     
    INSERT INTO TEACHERS(TNO,TNAME,TSEX,TBIRTHDAY,PROF,DEPART) VALUES (825,'王萍','女','1972-05-05','助教','计算机系');
     
    INSERT INTO TEACHERS(TNO,TNAME,TSEX,TBIRTHDAY,PROF,DEPART) VALUES (831,'刘冰','女','1977-08-14','助教','电子工程系');
    
    

    45道SQL问题

    1、 查询Students表中的所有记录的sname、ssex和class列。

    select sname,ssex,class from students;
    

    2、 查询教师所有的单位即不重复的Depart列。

    select distinct depart from teachers;
    

    3、 查询Students表的所有记录。

    select * from students;
    

    4、 查询Score表中成绩在60到80之间的所有记录。

    select * from scores where degree < =80 and degree >= 60;
    

    5、 查询Score表中成绩为85,86或88的记录。

    select * from scores where degree = 85 or degree = 86 or degree = 88;
    

    6、 查询Students表中“95031”班或性别为“女”的同学记录。

    select * from students where ssex = '女' or class = '95031' ;
    

    7、 以Class降序查询Students表的所有记录。

    select * from students order by class desc;
    

    8、 以Cno升序、Degree降序查询Score表的所有记录。

    select * from scores order by cno asc,degree desc;
    

    9、 查询“95031”班的学生人数。

    select count(*) from students where class = '95031';
    

    10、查询Score表中的最高分的学生学号和课程号。

    select sno,cno from scores where degree = (select max(degree) from scores);
    

    11、查询‘3-105’号课程的平均分。

    select avg(degree) from scores where cno = '3-105';
    

    12、查询Score表中至少有5名学生选修的并以3开头的课程的平均分数。
    讲解:

    (1)where是用于在初始表中筛选查询,having用于在where和group by的结果中查询。

    (2)having只用于group by,也就是说,having必须接在group by后面。

    (3)having可以使用聚合函数,例如count,sum之类的函数。

    优秀的group和having使用和讲解文章:https://www.jianshu.com/p/8b135d373df1

    select cno from scores group by cno

    select avg(degree) from scores where cno in (select cno from scores group by cno having count(*)>5) and cno like '3%'
    


    语句讲解:select avg(degree) from scores这个是主句,通过avg聚合函数,求解scores表上符合条件的degree的平均值,而where后面就是整个条件语句,cno表示符合条件的那个班级名字,in表示,con符合(select cno from scores group by cno having count(*)>5)这个条件,and表示cno同时要符合like '3%'(以3开头)这个条件。

    13、查询最低分大于70,最高分小于90的Sno列。

    讲解:这道题有点歧义,其实就是说sno列里面有多个类别,求解类别中具有最小值大于70,最大值小于90的特性那些类。

    select sno 
    
    from scores 
    
    group by sno 
    
    having max(degree) < 90 and min(degree)>70;
    


    语句讲解:select sno from scores表示主句,group by sno 表示对结果按sno进行分组,having表示当分组完成后,对每个分组结果进行判断,每个分组中如果符合max(degree) < 90 and min(degree)>70这个条件,则挑选出来。

    14、查询所有学生的Sname、Cno和Degree列。

    SELECT Sname,Cno,Degree 
    
    FROM Students INNER JOIN Scores
    
    ON(Students.Sno=Scores.Sno)
    
    ORDER BY Sname;
    


    语句讲解:这里涉及连接,select 表示挑选出来的数据,FROM Students INNER JOIN Scores表示学生表在左分数表在右,根据sno属性连接(ON(Students.Sno=Scores.Sno))。当students表没有某一行,但是右表有时,这时删除右表这一行,当students表有某一行,但右表没有时,这时右表对应添加上这一行,但是数值为空。

    15、查询所有学生的Sno、Cname和Degree列。

    SELECT Sno,Cname,Degree
    
    FROM Scores INNER JOIN Courses
    
    ON(Scores.Cno=Courses.Cno)
    
    ORDER BY Sno;
    


    inner表示内连接,表示只获取Scores.Cno和Course.Cno相同的部分。

    16、查询所有学生的Sname、Cname和Degree列。

    select students.sname,cname,degree
    from students join scores on (students.sno = scores.sno)
    join courses on (courses.cno = scores.cno)
    

    问:当多个表同时连接时,连接的顺序是什么?

    17、查询“95033”班所选课程的平均分。

    select avg(degree) as 'class = 95033'
    from scores 
    where sno  in (select sno from students where class='95033') 
    

    18、假设使用如下命令建立了一个grade表:

    create table grade(
    
    low   INTEGER,
    
    upp   INTEGER,
    
    rank   char(1));
    
    insert into grade values(90,100,'A');
    
    insert into grade values(80,89,'B');
    
    insert into grade values(70,79,'C');
    
    insert into grade values(60,69,'D');
    
    insert into grade values(0,59,'E');
    
    

    现查询所有同学的Sno、Cno和rank列。

    select sno,cno,degree,[rank]
    from grade join scores 
    on scores.degree
    between low and upp
    

    中括号的作用:
    1、有些可能是SQL里面的保留字,但是你又用了它做字段名 比如Action,用[Action] 就可以避免这个问题,如果直接Action
    SQL就要报错了。
    2、解决较长的中文名表名可能会被不识别的问题。

    这个题目有点没看懂

    19、查询选修“3-105”课程的成绩高于“109”号同学成绩的所有同学的记录。

    select * from students,Scores 
    where Scores.Cno='3-105' and students.Sno=Scores.Sno 
    and Scores.Degree>(select Degree 
    from Scores where Cno='3-105' and Sno='109')
    

    20、查询score中选学一门以上课程的同学中分数为非最高分成绩的记录。

    21、查询成绩高于学号为“109”、课程号为“3-105”的成绩的所有记录。

    22、查询和学号为108的同学同年出生的所有学生的Sno、Sname和Sbirthday列。

    23、查询“张旭“教师任课的学生成绩。

    24、查询选修某课程的同学人数多于5人的教师姓名。

    25、查询95033班和95031班全体学生的记录。

    26、查询存在有85分以上成绩的课程Cno.

    27、查询出“计算机系“教师所教课程的成绩表。

    28、查询“计算机系”与“电子工程系“不同职称的教师的Tname和Prof。

    29、查询选修编号为“3-105“课程且成绩至少高于选修编号为“3-245”的同学的Cno、Sno和Degree,并按Degree从高到低次序排序。

    30、查询选修编号为“3-105”且成绩高于选修编号为“3-245”课程的同学的Cno、Sno和Degree.

    31、查询所有教师和同学的name、sex和birthday.

    32、查询所有“女”教师和“女”同学的name、sex和birthday.

    33、查询成绩比该课程平均成绩低的同学的成绩表。

    34、查询所有任课教师的Tname和Depart.

    35  查询所有未讲课的教师的Tname和Depart.

    36、查询至少有2名男生的班号。

    37、查询Students表中不姓“王”的同学记录。

    38、查询Students表中每个学生的姓名和年龄。

    39、查询Students表中最大和最小的Sbirthday日期值。

    40、以班号和年龄从大到小的顺序查询Student表中的全部记录。

    41、查询“男”教师及其所上的课程。

    42、查询最高分同学的Sno、Cno和Degree列。

    43、查询和“李军”同性别的所有同学的Sname.

    44、查询和“李军”同性别并同班的同学Sname.

    45、查询所有选修“计算机导论”课程的“男”同学的成绩表`

    参考:cnblogs.com/kun-boke/p/5749900.html

  • 相关阅读:
    支持向量机SVM知识点概括
    决策树知识点概括
    HDU 3081 Marriage Match II
    HDU 3572 Task Schedule
    HDU 4888 Redraw Beautiful Drawings
    Poj 2728 Desert King
    HDU 3926 Hand in Hand
    HDU 1598 find the most comfortable road
    HDU 4393 Throw nails
    POJ 1486 Sorting Slides
  • 原文地址:https://www.cnblogs.com/LY-CS/p/12714259.html
Copyright © 2011-2022 走看看