SQL选择语句

3
我是一名有用的助手,可以为您翻译文本。

我认为这是一个相当基础的问题,我在网站上查找过,但不确定要搜索什么才能找到答案。

我有一个看起来像这样的SQL表:

studentId  period  class  
1          1       math  
1          2       english  
2          1       math  
2          2       history

我正在寻找一个SELECT语句,它可以找到正在上第一节数学课和第二节英语课的学生ID。我尝试了类似于 SELECT studentID WHERE ( period = 1 AND class= "math" ) AND ( period = 2 AND class = "english" ) 的语句,但没有成功。我还考虑将我的表改为:
studentId  period1  period2  period3  period4  period5 etc  

但我认为我想添加除课程以外的事情,比如课外活动,并希望能够轻松扩展,而不必不断添加列。感谢您可以给我的任何帮助。
3个回答

3
尝试类似以下内容:
select studentid from table where ( period = 1 AND class= "math" ) or ( period = 2 AND class = 
"english" ) group by studentid having count(*) >= 2

这个想法是选择所有符合第一个条件或第二个条件的人,按人员分组,并通过检查分组后的行数来确定是否满足所有条件。


2

您可以使用子查询来分别执行每个查询,并仅获取两个子查询都匹配的结果。

Select StudentId FROM table WHERE 
    StudentId IN 
       (SELECT studentID FROM table WHERE ( period = 1 AND class= "math" ) ) 
AND 
    StudentId IN 
       (SELECT studentID FROM table WHERE ( period = 2 AND class= "english" ) ) 

编辑-新增

我自己没有测试过,但我对性能问题很感兴趣,所以我查了一下。我找到了这句话:

许多包含子查询的 Transact-SQL 语句可以用连接来替代。其他问题只能使用子查询提出。在 Transact-SQL 中,通常情况下,包含子查询和不包含子查询但语义等效的语句之间没有性能差异。然而,在某些需要检查存在性的情况下,连接可以获得更好的性能。否则,嵌套查询必须针对外部查询的每个结果进行处理,以确保消除重复项。在这种情况下,连接方法将产生更好的结果。以下是一个示例,显示了同时返回相同结果集的子查询 SELECT 和连接 SELECT:

这里:http://technet.microsoft.com/en-us/library/ms189575.aspx


真实但有点过头了,不是吗? :D 但是+1因为提供了一个正确的子查询示例。 - The Surrican
@Joe Hopfgartner:他想要的是INTERSECT,而David的方法是交集的规范公式。 - Martin v. Löwis
true @margin 但我喜欢这个答案,因为它展示了一个非常清晰的不同方法,子查询实际上也不会是首选的工具!但是理解不同的可能性很重要,因此最好尽可能简单地将它们呈现出来。 - The Surrican
@Joe Hopfgartner,这可能有些过度,如果性能成为问题,就不应该使用它,但是为了代码清晰度,我认为它非常好。你的答案也很好,但是就个人而言,如果我是维护程序员并且需要进行调整,我会考虑一下。不过,我投了赞成票,因为它肯定有效。 - David
好的,count/having解决方案会表现更好,因为它只有一个查询。没有任何连接,也没有子查询。 - The Surrican
显示剩余2条评论

2
你可以使用自连接实现该操作。
SELECT  t1.studentID  
FROM table t1
JOIN table t2 ON t1.studentID = t2.studentID   
WHERE ( t1.period = 1 AND t1.class= "math" )    
  AND ( t2.period = 2 AND t2.class = "english" ) 

在发现这篇文章之后,我正准备将其作为我的答案的第二种可能性,但你比我更快。太好了! - David

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接