数据库表结构及数据

建表

 CREATE TABLE Student
(
S# INT,
Sname nvarchar(32),
Sage INT,
Ssex nvarchar(8)
) CREATE TABLE Course
(
C# INT,
Cname nvarchar(32),
T# INT
) CREATE TABLE Sc
(
S# INT,
C# INT,
score INT
) CREATE TABLE Teacher
(
T# INT,
Tname nvarchar(16)
)

测试数据

 insert into Student select 1,N'刘一',18,N'男' union all
select 2,N'钱二',19,N'女' union all
select 3,N'张三',17,N'男' union all
select 4,N'李四',18,N'女' union all
select 5,N'王五',17,N'男' union all
select 6,N'赵六',19,N'女' insert into Teacher select 1,N'叶平' union all
select 2,N'贺高' union all
select 3,N'杨艳' union all
select 4,N'周磊' insert into Course select 1,N'语文',1 union all
select 2,N'数学',2 union all
select 3,N'英语',3 union all
select 4,N'物理',4 insert into SC
select 1,1,56 union all
select 1,2,78 union all
select 1,3,67 union all
select 1,4,58 union all
select 2,1,79 union all
select 2,2,81 union all
select 2,3,92 union all
select 2,4,68 union all
select 3,1,91 union all
select 3,2,47 union all
select 3,3,88 union all
select 3,4,56 union all
select 4,2,88 union all
select 4,3,90 union all
select 4,4,93 union all
select 5,1,46 union all
select 5,3,78 union all
select 5,4,53 union all
select 6,1,35 union all
select 6,2,68 union all
select 6,4,71

数据库多表查询之 where & INNER JOIN

在多表查询中,一些SQL开发人员更喜欢使用WHERE来做join,比如:

SELECT a.ID, b.Name, b.Date FROM Customers a, Sales b WHERE a.ID = b.ID;

  WHERE子句中使用的连接语句,在数据库语言中,被称为隐性连接。INNER JOIN……ON子句产生的连接称为显性连接。(其他JOIN参数也是显性连接)WHERE 和INNER JOIN产生的连接关系,没有本质区别,结果也一样。但是!隐性连接随着数据库语言的规范和发展,已经逐渐被淘汰,比较新的数据库语言基本上已经抛弃了隐性连接,全部采用显性连接了。

  缺点:在上面语句中,实际上是创建了两张表的笛卡尔积,所有可能的组合都会被创建出来。在笛卡尔连接中,在上面的例子中,如果有1000顾客和1000条销售记录,这个查询会先产生1000000个结果,然后通过正确的 ID过滤出1000条记录。 这是一种低效利用数据库资源,数据库多做100倍的工作。 在大型数据库中,笛卡尔连接是一个大问题,对两个大表的笛卡尔积会创建数10亿或万亿的记录。

为了避免创建笛卡尔积,应该使用INNER JOIN :

SELECT a.ID, b.Name, b.Date FROM Customers a INNER JOIN Sales b ON a.ID = b.ID;

  优点:如上面语句,使用inner join 这样数据库就只产生等于ID 的1000条目标结果。增加了查询效率。

练习题目

1.查询“001”课程比“002”课程成绩高的所有学生的学号;

select * from
(select S#,Score from SC where C#='001') a,
(select S#,Score from SC where C#='002') b
where a.S#=b.S# and a.Score>b.Score

2.查询平均成绩大于60分的同学的学号和平均成绩;
方法一:

select * from
(select S#,AVG(score) as av from sc
group by S# ) S
where S.av>60

方法二:

select S#,AVG(Score) as AvgScore
from SC
group by S#
having AVG(Score)>60

3.查询所有同学的学号、姓名、选课数、总成绩;

select S.S#,S.Sname,COUNT(C#) as CourseCount, SUM(score) as ScoreSum
from Student as S left join Sc as C
on S.S#=C.S#
group by S.S#,S.Sname
order by S.S#

4.查询姓“李”的老师的个数;

select count(distinct Tname) as count from Teacher where Tname like '李%'

5.查询没学过“叶平”老师课的同学的学号、姓名;

select S.S#,S.Sname
from Student as S
where S.S# not in
(select distinct(sc.S#) from SC sc,Course c,Teacher t where sc.C#=c.C# and c.T#=t.T# and t.Tname='叶平')

6.查询学过“001”并且也学过编号“002”课程的同学的学号、姓名;

--解法一:求交集
select s.S#,s.Sname
from Student s,SC sc
where s.S#=sc.S# and sc.C#=''
intersect
select s.S#,s.Sname
from Student s,SC sc
where s.S#=sc.S# and sc.C#=''
--解法二:使用exists
select s.S#,s.Sname
from Student s,SC sc
where s.S#=sc.S# and sc.C#='' and exists
(
select * from SC sc2 where sc.S#=sc2.S# and sc2.C#=''
)

EXISTS用于检查子查询是否至少会返回一行数据,该子查询实际上并不返回任何数据,而是返回值True或False。那么,这里我们来看一下in和exists的区别

  ①in 是把外表和内表作hash 连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询。

  ②一直以来认为exists比in效率高的说法是不准确的

 -->如果查询的两个表大小相当,那么用in和exists差别不大。

 -->如果两个表中一个较小,一个是大表,则子查询表大的用exists,子查询表小的用in。

(7)查询学过“叶平”老师所教的所有课的同学的学号、姓名;

--方法一
select s.S#,s.Sname
from Student s
where s.S# in
(
select S# from Sc sc where sc.C# in
(
select C# from Teacher t
inner join Course c on t.T#=c.T#
where t.Tname='叶平'
)
)
--方法二
select s.S#,s.Sname
from Student s
where s.S# in
(
select sc.S#
from SC sc,Course c,Teacher t
where c.C#=sc.C# and c.T#=t.T# and t.Tname='叶平'
group by sc.S#
having COUNT(sc.C#)=
(
select COUNT(c1.C#)
from Course c1,Teacher t1
where c1.T#=t1.T# and t1.Tname='叶平'
)
)

(8)查询课程编号“002”的成绩比课程编号“001”课程低的所有同学的学号、姓名;

  select s.S#,s.Sname from Student s,
(select sc1.S#,sc1.Score from SC sc1 where sc1.C#='') a,
(select sc2.S#,sc2.Score from SC sc2 where sc2.C#='') b
where s.S#=a.S# and s.S#=b.S# and a.S#=b.S# and a.Score<b.Score

(9)查询有课程成绩小于60分的同学的学号、姓名;

  select s.S#,s.Sname
from dbo.Student s
left join dbo.Sc sc
on s.S#=sc.S#
where sc.score < 60
group by s.S#,s.Sname
select s.S#,s.Sname
from Student s
where s.S# in
(
select distinct(sc.S#) from SC sc
where s.S#=sc.S# and sc.Score<60
)

(10)查询没有学全所有课的同学的学号、姓名;(可以从学全的学生中取反)

select s.S#,s.Sname
from Student s
where s.S# not in
(
select sc.S# from SC sc
group by sc.S#
having COUNT(distinct sc.C#)= --按照学号分组计算每个学号总的课程数
(
select COUNT(distinct c.C#) from Course c --计算总得课程数
)
)

(11)查询至少有一门课与学号为“001”的同学所学相同的同学的学号和姓名;

--方法一
select s.S#,s.Sname from dbo.Student s
where s.S# in
(
select distinct(sc.S#) from dbo.Sc where sc.C#
in(select distinct(sc.C#) from dbo.Sc sc where sc.S# = '')
)
--方法二
select distinct(s.S#),s.Sname from dbo.Student s
inner join dbo.Sc
on s.S# =sc.S# and s.S# in
(
select distinct(sc.S#) from dbo.Sc where sc.C#
in(select distinct(sc.C#) from dbo.Sc sc where sc.S# = '')
)
--方法三
select distinct(s.S#),s.Sname
from Student s,SC sc
where s.S#=sc.S# and sc.C# in
(
select distinct(sc2.C#) from SC sc2
where sc2.S#=''
)
order by s.S# asc

(12)查询至少学过学号为“001”同学所有一门课的其他同学学号和姓名;(感觉跟11题有重叠)

select distinct(s.S#),s.Sname
from Student s,SC sc
where s.S#=sc.S# and s.S#!='' and sc.C# in
(
select distinct(sc2.C#) from SC sc2
where sc2.S#=''
)
order by s.S# asc

(13)把“SC”表中“叶平”老师教的课的成绩都更改为此课程的平均成绩;

update SC set Score=
(
select AVG(score) from SC sc,Course c,Teacher t
where sc.C#=c.C# and c.T#=t.T# and t.Tname='叶平'
)
where C# in
(
select distinct(sc.C#) from SC sc,Course c,Teacher t
where sc.C#=c.C# and c.T#=t.T# and t.Tname='叶平'
)

查询“叶平”老师教的课

select * from dbo.Sc sc where sc.C# in
(
select c.C# from dbo.Teacher t
inner join dbo.Course c
on t.T#= c.T#
where t.Tname='叶平'
)

--(14)查询和“002”号的同学学习的课程完全相同的其他同学学号和姓名;

select s.S#,s.Sname
from Student s
where s.S#!='' and s.S# in
(
select distinct(S#) from SC
where C# in (select C# from SC where S#='')
group by S#
having COUNT(distinct C#)=
(
select COUNT(distinct C#) from SC
where S#=''
)
)

(15)删除学习“叶平”老师课的SC表记录;

delete from SC where C# in
(
select c.C# from Course c,Teacher t
where c.T#=t.T# and t.Tname='叶平'
)

(16)向SC表中插入一些记录,这些记录要求符合以下条件:①没有上过编号“002”课程的同学学号;②插入“002”号课程的平均成绩;

  insert into SC
select s.S#,'' C#,(select AVG(sc.score) from dbo.Sc sc where sc.C# = '') score
from dbo.Student s where s.S# not in
(
select distinct(sc.S#) from dbo.Sc sc where sc.C# =''
)

(17)按平均成绩从低到高显示所有学生的“语文”、“数学”、“英语”三门的课程成绩,按如下形式显示: 学生ID,语文,数学,英语,有效课程数,有效平均分;

select t.S# as '学生ID',
(select Score from SC sc where sc.S#=t.S# and sc.C#='') as '语文',
(select Score from SC sc where sc.S#=t.S# and sc.C#='') as '数学',
(select Score from SC sc where sc.S#=t.S# and sc.C#='') as '英语',
COUNT(t.C#) as '有效课程数',
AVG(t.Score) as '有效平均分'
from SC t
group by t.S#
order by AVG(t.Score)

sql中自连接的使用

select sc2.S# as '学生ID',
(select Score from SC sc1 where sc1.S#=sc2.S# and sc1.C#='') as '语文'
from SC sc2
group by sc2.S#

资料

http://www.cnblogs.com/edisonchou/p/3878135.html

SQL Server 基础之《学生表-教师表-课程表-选课表》的更多相关文章

  1. sql server 很好的基础练习 <学生表-老师表-课程表-选课表>

    表结构 --学生表tblStudent(编号StuId.姓名StuName.年龄StuAge.性别StuSex) --课程表tblCourse(课程编号CourseId.课程名称CourseName. ...

  2. SQL server基础知识(表操作、数据约束、多表链接查询)

    SQL server基础知识 一.基础知识 (1).存储结构:数据库->表->数据 (2).管理数据库 增加:create database 数据库名称 删除:drop database ...

  3. SQL Server 2008 R2中,变表的右键弹出菜单中的“选择前1000行”为“选择所有行”

    原文:SQL Server 2008 R2中,变表的右键弹出菜单中的"选择前1000行"为"选择所有行" 从SQL Server 2008开始,微软为了提高查询 ...

  4. 何查询SQL Server数据库没有主键的表并增加主键

    SQL Server数据库中,如果一个表没有主键,我们该如何查询呢?本文我们主要就介绍了如何查询数据库中没有主键的表名并为其增加主键的方法,希望能够对您有所帮助. 该功能的实现代码如下: declar ...

  5. SQL SERVER 判断是否存在数据库、表、列、视图

    SQL SERVER 判断是否存在数据库.表.列.视图 --1. 判断数据库是否存在 IF EXISTS (SELECT * FROM SYS.DATABASES WHERE NAME = '数据库名 ...

  6. SQL SERVER学习笔记:临时表与表变量

    本文主要摘自徐海蔚的<Microsoft SQL SERVER企业级平台管理实践> 表变量可以作为存储过程的返回参数,而临时表不行.(存疑?表值参数只在SQL SERVER2008才开始支 ...

  7. 《SQL Server基础——SQL语句》

    SQL Server基础--SQL语句       一.创建和删除数据库: 1.创建数据库(默认化初始值) 格式: CREATE DATABASE 数据库名称 例如: CREATE DATABASE ...

  8. 数据库开发基础-SQl Server 基础

    SQL Server 基础 1.什么是SQL Server SQL:Structured Query Language  结构化查询语言 SQL Server是一个以客户/服务器(c/s)模式访问.使 ...

  9. 【SQL Server】SQL Server基础之存储过程

    SQL Server基础之存储过程  阅读目录 一:存储过程概述 二:存储过程分类 三:创建存储过程 1.创建无参存储过程 2.修改存储过程 3.删除存储过程 4.重命名存储过程 5.创建带参数的存储 ...

  10. Sql Server 基础语法

    来自:http://www.cnblogs.com/AaronYang/archive/2012/04/24/2468093.html Sql Server 基础语法 -- 查看数据表 select  ...

随机推荐

  1. Goldengate常用命令

    1.Goldengate的起停 启动goldengate   a> 启动goldengate时最好先从target节点开始,然后是source节点.否则data pump进程可能会由于没有收到t ...

  2. 使用appium模拟用户发送短信

    一段简单粗糙的代码.主要是实现的功能是模拟用户发送短信的功能. python版本3.5.2 appium版本1.4.16.1 from appium import webdriver desired_ ...

  3. Hibernate和JDBC、EJB比较

    参考:http://m.blog.csdn.net/article/details?id=7228061 一.Hibernate是JDBC的轻量级的对象封装,它是一个独立的对象持久层框架,和App S ...

  4. 基于jQuery的web在线流程图设计器GooFlow

    简易的流程图设计控件,效果图: JavaScript源文件在GooFlow.js中,样式文件是GooFlow2.css.可以自定义样式. GooFlow_item类是每个项的样式属性. 但估计实现任务 ...

  5. 【PL/SQL练习】游标cursor :oracle 在执行sql语句时,为sql语句所分配的一个私有的内存区域

    隐式游标:一次只能返回一行结果(不需要定义,默认自动建立)  显式游标: 需要开发人员提前定义,可以通过循环的方式处理游标里的sql语句,返回多行结果    隐式游标的属性:   sql%rowcou ...

  6. 在使用 AjaxFileUpload 上传文件时,在项目发布到 iis 后,图片不能预览

    在使用 AjaxFileUpload  上传文件时,图片已经上传成功了,在站点没有发布时,可以预览,可是在项目发布到 iis 后,图片就不能预览,在网上找了很多的方案也没解决,最后的解决方案如下: 1 ...

  7. jqmobi 子菜单 高亮效果

    在jqmobi 中经常用到一个 子菜单 单击某一个选项 希望能高亮:所以我是这样做的1.HTML的页面显示是这样的 <div class="order_subheader01" ...

  8. jQuery 遍历 - map() 方法

    定义和用法 map() 把每个元素通过函数传递到当前匹配集合中,生成包含返回值的新的 jQuery 对象. 例子1: 构建表单中所有值的列表: <p><b>value为: &l ...

  9. maven auto-config 多环境自动打包

    摘自:http://doc.okbase.net/bjhecwq/archive/118121.html maven有许多优秀的插件,最近在研究打包中替换多重环境的配置,同事介绍使用阿里的auto-c ...

  10. pig中变量

    pig中的变量都是找到$变量然后替换,有点像宏,完全就是替换,看如下例子 %default m 'you';b = load 'a' as (a:chararray);c = foreach b ge ...