查询“全部”

关系型数据库的查询语言(SQL)具有集合查询的特性,能够很方便地查询匹配任意一个数据的所有数据行,例如,有exists子句表示存在,表示匹配任意一行数据,但是如何表示匹配全部的数据行?例如,大学开设了C1-C9共计9门课程,如何查询选修了所有课程的学生?这就是“匹配全部”语义的一个经典实例。

使用以下代码创建示例数据,后面我会使用两种不同的方式实现获取“选修全部”课程的学生的逻辑。

--create table
create table dbo.student
(
student_no int,
student_name varchar(10)
)

create table dbo.course
(
course_no int,
course_name varchar(10)
)

create table dbo.student_course
(
student_no int,
course_no int
)

--insert data
insert into dbo.student(student_no,student_name)
values(1,'stu_a'),(2,'stu_b'),(3,'stu_c'),(4,'stu_d')

insert into dbo.course(course_no,course_name)
values(11,'English'),(12,'Math'),(13,'Chinese')

insert into dbo.student_course(student_no,course_no)
values(1,11),(1,12),(1,13),(2,11),(2,13),(3,11),(3,12),(4,12)
View Code

1,逆向思维,“双重否定”成肯定

exists表示匹配任意一个,not exists表示不存在,使用两个 not exists 表示:不存在任何一个课程该学生没有选修,换句说法,就是该学生选修了所有的课程:

select s.student_name
from dbo.student s
where not exists 
(
    select NULL
    from dbo.course c
    where not EXISTS
    (
        select NULL
        from dbo.student_course sc
        where sc.student_no=s.student_no
            and sc.course_no=c.course_no
    )
)

2,正向思维,使用group by 子句实现

根据学号对选课表进行分组,如果某一个学生选修的课程的数量和课程表的总数量相同,说明该学生选修了所有的课程:

declare @CouseCount int

select @CouseCount=count(0)
from dbo.course

;with cte as 
(
select sc.student_no
from dbo.student_course sc
inner join dbo.course c
    on sc.course_no=c.course_no
group by sc.student_no
having count(0)=@CouseCount
)
select s.student_name
from dbo.student s
inner join cte c
    on s.student_no=c.student_no

这是一种正向的思维方法,在思路上很好想明白,也比较好理解。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

悦光阴

你的鼓励是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值