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

原文地址:https://www.cnblogs.com/take-it-easy/p/11775991.html

时间: 2024-10-27 18:24:11

sql 经典查询50题 思路(一)的相关文章

sql语句练习50题

sql语句练习50题 Student(Sid,Sname,Sage,Ssex) 学生表 Course(Cid,Cname,Tid) 课程表 SC(Sid,Cid,score) 成绩表 Teacher(Tid,Tname) 教师表 练习内容: 1.查询“某1”课程比“某2”课程成绩高的所有学生的学号: SELECT a.sid FROM (SELECT sid,score FROM SC WHERE cid=1) a,(SELECT sid,score FROM SC WHERE cid=3) b

Oracle SQL 经典查询练手第三篇

Oracle SQL 经典查询练手第三篇 本文分享的是Oracle SQL的经典查询第三篇,仅仅是作者自己的见解,如有问题,希望您给出建议或者方法.同时,欢迎广大读者们补充,如果您有经典的查询方式也可以拿出来我们共同分享,共同成长,共同进步. 本计算机上使用的是Oracle 11.2.0版本,使用scott用户登陆.使用的是系统自带的表. 表结构: describe employees; describe departments; describe locations; select *from

JAVA经典算法50题(转)

转载请注明出处:http://blog.csdn.net/l1028386804/article/details/51097928 JAVA经典算法50题 [程序1]   题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第四个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?1.程序分析:兔子的规律为数列1,1,2,3,5,8,13,21.... [java] view plain copy public class Demo01 { public s

sql语句练习50题(Mysql版) 围观

表名和字段 –1.学生表 Student(s_id,s_name,s_birth,s_sex) –学生编号,学生姓名, 出生年月,学生性别 –2.课程表 Course(c_id,c_name,t_id) – –课程编号, 课程名称, 教师编号 –3.教师表 Teacher(t_id,t_name) –教师编号,教师姓名 –4.成绩表 Score(s_id,c_id,s_score) –学生编号,课程编号,分数 测试数据 --建表 --学生表 CREATE TABLE `Student`( `s_

sql语句练习50题(我自己写的答案,还没写完)

Student(Sid,Sname,Sage,Ssex) 学生表Course(Cid,Cname,Tid) 课程表SC(Sid,Cid,score) 成绩表Teacher(Tid,Tname) 教师表练习内容:1.查询“某1”课程比“某2”课程成绩高的所有学生的学号:SELECT a.Sid FROM SC AS a ,SC AS bWhere a.Cid IN (SELECT Cid FROM Course Where Cname="某1")AND b.Cid IN (SELECT

Oracle SQL:经典查询练手第一篇

讨论一些常见的SQL经典查询 使用Oracle的Scott用户 表结构如下: emp表 dept表 工资=薪金+佣金 工资=sal+comm 表中数据如下: emp: dept: 问题列表: 用SQL完成以下问题列表: 列出至少有一个员工的所有部门. 列出薪金比“SMITH”多的所有员工. 列出所有员工的姓名及其直接上级的姓名. 列出受雇日期早于其直接上级的所有员工. 列出部门名称和这些部门的员工信息,同时列出那些没有员工的部门 列出所有“CLERK”(办事员)的姓名及其部门名称. 列出最低薪金

SQL经典题及答案

关于group by 表内容: 2005-05-09 胜 2005-05-09 胜 2005-05-09 负 2005-05-09 负 2005-05-10 胜 2005-05-10 负 2005-05-10 负 如果要生成下列结果, 该如何写sql语句? 胜 负 2005-05-09 2 2 2005-05-10 1 2 ------------------------------------------ create table #tmp(rq varchar(10),shengfu nch

SQL 经典语句

15题需要再分析.没弄懂 使用scott/tiger用户下的emp表和dept表完成下列练习, 表的结构说明如下 emp员工表(empno员工号/ename员工姓名/job工作/mgr上级编号/hiredate受雇日期/sal薪金/comm佣金/deptno部门编号) dept部门表(deptno部门编号/dname部门名称/loc地点) 工资 = 薪金 + 佣金 1.列出至少有一个员工的所有部门. 2.列出薪金比“SMITH”多的所有员工. 3.列出所有员工的姓名及其直接上级的姓名. 4.列出

sql分级查询

1 USE [zxerp] 2 GO 3 /****** Object: StoredProcedure [dbo].[Pro_GrossProfitCount] Script Date: 06/26/2014 08:48:10 ******/ 4 SET ANSI_NULLS ON 5 GO 6 SET QUOTED_IDENTIFIER ON 7 GO 8 ALTER procedure [dbo].[Pro_GrossProfitCount] 9 @fcomid int, 10 @star