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) に関連付けられています。Student 2 は (12,13,14) に関連付けられていますが、(11,15) には関連付けられていません。

section_id の「グループ 2」の場合: (21,22,23,24,25) 生徒 2 は (21,22,23) に関連付けられていますが、(24,25) には関連付けられていません。

section_id (12,13,14) が与えられた場合、それらの section_id に関連付けられている Student_id を選択する必要がありますが、section_id (11,15) には関連付けられていません。

たとえば、section_id の (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

2 つの選択を交差させる必要があります。

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

そしてフィドル

または NOT EXISTS を使用:

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 に答える