0

抱歉标题很糟糕,我想不出更好的方式来描述我的问题,所以我通过示例很好地解释它来弥补它。

设置

如果您想继续,这里是为我的问题创建表的 SQL:

CREATE TABLE `student_sections` (`student_id` int(11) NOT NULL, `section_id` int(11) NOT NULL);
INSERT INTO `student_sections` (`student_id`,`section_id`) VALUES (1,11);
INSERT INTO `student_sections` (`student_id`,`section_id`) VALUES (1,12);
INSERT INTO `student_sections` (`student_id`,`section_id`) VALUES (1,13);
INSERT INTO `student_sections` (`student_id`,`section_id`) VALUES (1,14);
INSERT INTO `student_sections` (`student_id`,`section_id`) VALUES (1,15);
INSERT INTO `student_sections` (`student_id`,`section_id`) VALUES (2,12);
INSERT INTO `student_sections` (`student_id`,`section_id`) VALUES (2,13);
INSERT INTO `student_sections` (`student_id`,`section_id`) VALUES (2,14);
INSERT INTO `student_sections` (`student_id`,`section_id`) VALUES (2,21);
INSERT INTO `student_sections` (`student_id`,`section_id`) VALUES (2,22);
INSERT INTO `student_sections` (`student_id`,`section_id`) VALUES (2,23);

结果如下表:

| student_sections        |
|-------------------------|
| student_id | section_id |
|------------|------------|
| 1          | 11         |
| 1          | 12         |
| 1          | 13         |
| 1          | 14         |
| 1          | 15         |
| 2          | 12         |
| 2          | 13         |
| 2          | 14         |
| 2          | 21         |
| 2          | 22         |
| 2          | 23         |

设想

我有一个“组”的部分,我必须找到与部分组合相关联的所有学生。我的应用程序将有几个“组”的部分。

对于 section_id 的“组 1”:(11,12,13,14,15) 学生 1 与所有部分 (11,12,13,14,15) 相关联。学生 2 与 (12,13,14) 相关联,但不与 (11,15) 相关联。

对于 section_id 的“组 2”:(21,22,23,24,25) 学生 2 与 (21,22,23) 相关联,但不与 (24,25) 相关联。

给定 section_id's (12,13,14) 我需要选择与那些 section_id's 相关联的 student_id,而不是与 section_id's (11,15) 相关联。

例如,如果给定 section_id's (12,13,14) 我想选择 student_id (2)。即使 student_id 1 与 section_id (12,13,14) 相关联,她也与 11 和 15 相关联,所以我不希望她的 id 返回。

此查询的更高目的是我将使用它作为子查询来选择给定部分组合的学生列表。

例如,如果给定 section_id 的 (12,13)​​,则不会返回任何结果。

我试过的

我尝试混合使用 IN 和 NOT IN,但因为 5 行的 student_id 1 和 3 行与 (12,13,14) 相关联,所以以下查询中的 DISTINT() 返回 student_id 1 和 2。

SELECT
    DISTINCT(student_id)
FROM
    student_sections
WHERE
    section_id IN (12,13,14)
    AND section_id NOT IN (11,15)

2月1日更新

我添加了一些额外的用例数据,稍微改变了查询的要求。一个学生将被安排针对几个“组”的部分。

4

4 回答 4

3

对于这种类型的查询,我建议使用having子句进行聚合:

select ss.student_id
from student_sections ss
group by ss.student_id
having max(case when section_id = 12 then 1 else 0 end) = 1 and
       max(case when section_id = 13 then 1 else 0 end) = 1 and
       max(case when section_id = 14 then 1 else 0 end) = 1 and
       max(case when section_id not in (12, 13, 14) then 1 else 0 end) = 0

这是相同想法的一个更简单的版本:

select ss.student_id
from student_sections ss
group by ss.student_id
having count(distinct section_id) = 3 and
       count(distinct case when section_id in (12, 13, 14) then section_id end) = 3

我喜欢第一个版本,因为它概括了许多“组内组”问题。

于 2013-01-30T00:21:21.890 回答
1

您需要 INTERSECT 两个选择:

SELECT student_id FROM student_sections
WHERE section_id IN (12,13,14)
   INTERSECT
SELECT student_id WHERE
   section_id NOT IN (11,15)
于 2013-01-30T00:45:14.683 回答
0
SELECT student_id
     , COUNT(*) x
     , COUNT(CASE WHEN section_id IN(12,13,14) THEN 'foo' END) y
  FROM student_sections 
 GROUP 
    BY student_id;
于 2013-01-30T00:25:21.883 回答
0

这是另一种选择,但我喜欢@Gordon 的回答:

SELECT ss.student_id
FROM student_sections ss
     left join (select student_id 
                  from student_sections 
                  where section_id NOT IN (12,13,14)
                  ) s on ss.student_id = s.student_id
WHERE s.student_id is null
GROUP BY ss.student_id
HAVING Count(distinct ss.section_id) = 3

还有小提琴

或使用不存在:

SELECT ss.student_id
FROM student_sections ss
WHERE NOT EXISTS (
  select null
  from student_sections 
  where section_id NOT IN (12,13,14)
    and student_id = ss.student_id
  )
GROUP BY ss.student_id
HAVING Count(distinct ss.section_id) = 3

祝你好运。

于 2013-01-30T00:27:45.320 回答