zoukankan      html  css  js  c++  java
  • sql 经典查询50题 思路(一)

    因为需要提高一下sql的查询能力,当然最快的方式就是做一些实际的题目了。选择了这个sql的50题,这次大概做了前10题左右,把思路放上来,也是一个总结。

    具体题目见:

    https://zhuanlan.zhihu.com/p/72223558

    第一部分的题目主要使用的技术是连表查询和子查询,难倒不难,主要是要把思路转换过来。

    首先画出一个各个表之间的关系图(没画图之前关系老是搞不清)

     1.查询" 01 "课程比" 02 "课程成绩高的学生的信息及课程分数

    学生的信息在表1当中,课程成绩在表4当中,当然要用到连表查询。

    这里很有普遍性的一个问题是:要从表4中找出Sid相同,但是Cid为1的score大于Cid为2的score的记录。这里要使用子查询,分别限定条件为Cid=‘1’,Cid='2',变成两个表,再查满足条件的就很简单了。

    select Student.SId,Student.Sname,Student.Sage,Student.Ssex,r.科目一成绩,r.科目二成绩
    from study.dbo.Student 
    right join
    (select t1.SId as 学生ID,t1.score as 科目一成绩,t2.score as 科目二成绩
    from 
    (select SId,score from study.dbo.SC where CId='01')as t1,
    (select SId,score from study.dbo.SC where CId='02')as t2
    where t1.SId=t2.SId and t1.score>t2.score) as r
    on Student.SId=r.学生ID

    join -- on这个也是常用的思路,当要连接两个某一列相关的表时。

    1.1查询存在" 01 "课程但可能不存在" 02 "课程的情况(不存在时显示为 null )

    和第一题思路类似,注意以01课程为准,所以要用left join

    select *
    from    
    (select SId,score from study.dbo.SC where CId='01') as t1
    left join
    (select SId,score from study.dbo.SC where CId='02') as t2
    on t1.SId=t2.SId


    1.2 查询同时存在01和02课程的情况

    很简单,用inner join,求两表交集

    select t1.SId,t1.score,t2.score
    from    
    (select SId,score from study.dbo.SC where CId='01') as t1
    inner join
    (select SId,score from study.dbo.SC where CId='02') as t2
    on t1.SId=t2.SId


    1.3查询选择了02课程但没有01课程的情况

    我的思路是还是用一个right join,然后判断NULL值,不知道会不会比not in效率高

    select t2.SId,t2.score
    from    
    (select SId,score from study.dbo.SC where CId='01') as t1
    right join
    (select SId,score from study.dbo.SC where CId='02') as t2
    on t1.SId=t2.SId
    where t1.score is null

    2.查询平均成绩大于等于 60 分的同学的学生编号和学生姓名和平均成绩

    肯定要连表,有表一有表四。平均成绩涉及到group by,对平均成绩的限制涉及到having语句

    select  t1.SId,t1.avg_score,t2.Sname
    from
    (
    select SId,AVG(score) as avg_score
    from study.dbo.SC
    group by SId
    having AVG(score)>60
    ) as t1
    inner join study.dbo.Student as t2
    on t1.SId=t2.SId

    3.查询在 SC 表存在成绩的学生信息
    依然是连表查询,表一的sid等于表四的sid,去除重复值使用DISTINCT即可

    select DISTINCT Student.SId,Student.Sname,Student.Sage,Student.Ssex
    from study.dbo.SC
    inner join Student
    on SC.SId=Student.SId

    4.查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩(没成绩的显示为 null )

    依然是连表查询,left join

    select Student.*,t2.count_id,t2.avg_score
    from
    Student
    left join
    (select SId,count(CId) as count_id ,avg(score)as avg_score from study.dbo.SC group by SId) as t2
    on Student.SId=t2.SId

    4.1 查有成绩的学生信息

    inner join,不赘述

    select Student.*,t2.count_id,t2.avg_score
    from
    Student
    inner join
    (select SId,count(CId) as count_id ,avg(score)as avg_score from study.dbo.SC group by SId) as t2
    on Student.SId=t2.SId

    5.查询「李」姓老师的数量

    最简单的一题,知道like这种模糊查询就行

    select COUNT(*)
    from Teacher
    where Tname like '李%'

    6.查询学过「张三」老师授课的同学的信息

    这个有意思,代表着从一张表跳到另一张表找信息

    第一个思路当然是用join,多个表一个一个on连接起来

    select Student.*
    from
    (select tid from Teacher where Tname='张三') as t1
    inner join Course on t1.tid=Course.TId
    inner join SC on Course.CId=SC.CId
    inner join Student on SC.SId=Student.SId

    但是也有另一种写法

    select study.dbo.Student.*
    from teacher,study.dbo.Course  ,study.dbo.student,study.dbo.sc
    where teacher.Tname='张三' and   teacher.TId=Course.TId and   Course.CId=sc.CId and   sc.SId=student.SId

    直接from多个表,在where里写=

    我查了一下,其实这种方式是用了隐式的inner join,效率差异不大


    7.查询没有学全所有课程的同学的信息

    查到没有学全所有课程同学的sid很简单,在表4中查询。同学的信息用inner join联表1查询实现。

    SELECT *
    FROM study.dbo.Student as t1
    inner join
    (select Student.SId from Student
    left join
    study.dbo.SC
    on Student.SId=SC.SId
    group by Student.SId
    having COUNT(SC.CId)!=(select count(*) from study.dbo.Course)) as t2
    on t1.SId=t2.SId
  • 相关阅读:
    对网页图片的增删改管理
    还没搞完的排序(后期更新)
    web实现图片动态
    C++11 笔记
    如何解决刷新系统桌面响应速度很慢的问题
    CGrowableArray解析 _ DXUT容器
    测试...外部指针访问private
    CustomUI Direct3D9_Sample
    缺少.lib文件导致的Link2019 解决方案汇总
    在DirectX9中使用DXUT定制按钮来控制模型旋转的问题
  • 原文地址:https://www.cnblogs.com/take-it-easy/p/11775991.html
Copyright © 2011-2022 走看看