2017-07-05 17 views
1

我有3张桌子。SQL:如何过滤连接操作中的集合?

CREATE TABLE students (
    student_id INT   NOT NULL, 
    student_name VARCHAR(10) NOT NULL, 
    PRIMARY KEY (student_id) 
); 

CREATE TABLE courses (
    course_id INT   NOT NULL, 
    course_name VARCHAR(10) NOT NULL, 
    PRIMARY KEY (course_id) 
); 

CREATE TABLE student_courses (
    student_id INT NOT NULL, 
    course_id INT 
); 

我想让所有被分配到2门以上课程的学生。这里是我的尝试:

SELECT 
    s.student_name, 
    c.course_name 
FROM students s 
    JOIN student_courses sc 
    ON s.student_id = sc.student_id 
    JOIN courses c 
    ON c.course_id = sc.course_id 
WHERE s.student_id 
    IN (SELECT s.student_id 
     FROM students s 
     JOIN student_courses sci 
      ON s.student_id = sci.student_id 
     JOIN courses ci 
      ON ci.course_id = sci.course_id 
     GROUP BY s.student_id 
     HAVING COUNT(s.student_id) > 2); 

它的工作原理。但我认为这应该是一个更简单的方法。

+0

有,但为目的的测试它应该没问题。 –

+0

如果您有窗口函数可用,您可以使用CTE并为cte中的每个学生计算课程,然后选择计数大于2的位置,或者使用存在位置而不是in。存在可以提前逃避。 – xQbert

回答

1

从技术上讲,这将足够了:

SELECT student_id FROM student_courses GROUP BY student_id HAVING count(*) > 2 

它返回的学生证。如果您想了解学生的详细信息分配给超过2个疗程

任何学生,你可以别名此查询并加入其他表它

SELECT ... FROM students s INNER JOIN 
(SELECT student_id FROM student_courses GROUP BY student_id HAVING count(*) > 2) a ON a.student_id = s.id 

请注意,您的规范是在你的“工作原理”代码相持不下,因为该代码表示​​HAVING count(*) > 1

“尽量避免使用对名单的比你不再会愿意手工编写”是一个经验法则我总是试图实现