一个看似很简单的SQL却难倒了很多人
一个选课表,有学生id,课程id,老师id,要求选出同时选了语文和数学的学生
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | USE [tempschool] GO /****** 对象: Table [dbo].[SelectC] 脚本日期: 07/02/2015 11:04:55 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[SelectC]( [ID] [ int ] IDENTITY(1,1) NOT NULL, [Sid] [ int ] NULL, [Cid] [ int ] NULL, [Tid] [ int ] NULL, CONSTRAINT [PK_SelectC] PRIMARY KEY CLUSTERED ( [ID] ASC )WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY] ) ON [PRIMARY] |
插入一些模拟数据, 假设CID=1和CID=2的分别是语文和数学,那么根据下图,同时选了语文和数学的应该是1号和5号学生
先不要看答案,在脑子里写一个sql,然后再往下看
一开始得到了很多错误的答案,也是最容易出现的答案
1 2 3 4 5 | --错误的答案,一条记录都找不到 select * from selectC where cid=1 and cid=2 --错误的答案,只选了一门语文的学生也会出现在记录中 select * from selectC where cid=1 or cid=2 |
那么正确的答案应该怎么做呢,目前我找到3种方法,
方法一:
1 2 3 | select a.sid from SelectC as a left join SelectC as b on b.sid = a.sid where a.cid =1 and b.cid =2 |
对了,笛卡尔乘积,无限关联就可以选出同时选了语文数学英语等等等等的情况
方法二:
1 2 3 4 5 6 | SELECT sid FROM SelectC WHERE (cid = 1) OR (cid = 2) GROUP BY sid HAVING (COUNT(*) >= 2) |
这是第二种,首先先通过条件or选择出所有的语文或者数学的,然后根据sid汇总,只要count数量大于2的就是同时选择了语文和数学的,如果要扩展再多的就是修改count的数量和or的条件
方法三:
1 2 3 | select distinct sid from selectC where sid in ( select sid from selectc where cid = 1) and sid in ( select sid from selectc where cid = 2) |
第三种方法似乎效率就比较低了,需要用in来做查询。
不知道大家还有没有其他的写法
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端