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号学生
一开始得到了很多错误的答案,也是最容易出现的答案
--错误的答案,一条记录都找不到 select * from selectC where cid=1 and cid=2 --错误的答案,只选了一门语文的学生也会出现在记录中 select * from selectC where cid=1 or cid=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
对了,笛卡尔乘积,无限关联就可以选出同时选了语文数学英语等等等等的情况
方法二:
SELECT sid FROM SelectC WHERE (cid = 1) OR (cid = 2) GROUP BY sid HAVING (COUNT(*) >= 2)
这是第二种,首先先通过条件or选择出所有的语文或者数学的,然后根据sid汇总,只要count数量大于2的就是同时选择了语文和数学的,如果要扩展再多的就是修改count的数量和or的条件
方法三:
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来做查询。
不知道大家还有没有其他的写法