MySQL查询检查缺少的多对多关系

时间:2019-04-26 09:50:24

标签: mysql sql

我有三个MySQL表,如下所示:

 CREATE TABLE  students (
  StudentName VARCHAR(255),   
  StudentID VARCHAR(255) 
  );

 CREATE TABLE  courses (
  CourseName VARCHAR(255),   
  CourseID VARCHAR(255) 
  );

CREATE TABLE  participation (
 CourseID VARCHAR(255),   
 StudentID VARCHAR(255) 
 );

INSERT INTO students
 VALUES ('Biplab',  '04CS9501'),
       ('Amit',  '05CS3001'),
       ('Rahul',  '05CS3003'),
       ('Divya',  '05CS3004'),
       ('Praveen',  '05CS3005');


INSERT INTO courses
 VALUES ('Business and Science',  'B3D'),
        ('Economics',  'B3B'),
        ('Business and Laws',  '63O1'),
        ('Economics and Laws',  '63K1'),
        ('Economics and Science',  'B3E');

  INSERT INTO participation 
    VALUES ('B3D',  '04CS9501'),
    ('B3D',  '05CS300'),
    ('B3D',  '05CS3003'),
    ('B3B',  '05CS3003'),
    ('B3B',  '05CS3004'),
    ('63O1',  '04CS9501'),
    ('63O1',  '05CS3004'),
    ('63K1',  '05CS3001'),
    ('63K1',  '05CS3003'),
    ('63K1',  '05CS3004');

假设每个学生都必须上一门课程,并且每个课程都必须有学生参与,我想通过能够确定没有学生的课程或没有学生的课程来测试数据的完整性课程参与。在这种情况下,学生为“ Praveen”,课程为“经济与科学”。

如何构造这样的查询?

2 个答案:

答案 0 :(得分:2)

您可以使用以下解决方案获得不带participation的所有课程:

-- to get all empty courses using "WHERE NOT ... IN ..."
SELECT * 
FROM courses 
WHERE NOT CourseID IN (SELECT CourseID FROM participation)

-- or using "LEFT JOIN"
SELECT c.*
FROM courses c LEFT JOIN participation p ON c.CourseID = p.CourseID
WHERE p.StudentID IS NULL

...以及以下解决方案,以使学生没有participation

-- to get all students wihtout participation using "WHERE NOT ... IN ..."
SELECT * 
FROM students 
WHERE NOT StudentID IN (SELECT StudentID FROM participation)

-- or using "LEFT JOIN"
SELECT s.*
FROM students s LEFT JOIN participation p ON s.StudentID = p.StudentID 
WHERE p.CourseID IS NULL

您也可以使用LEFT JOIN来获取期望的记录。另外,您可以使用UNION ALL和附加列来通过一个查询获取所有记录:

SELECT 'Student' AS type, s.StudentID AS 'ID', s.StudentName AS 'Name' 
FROM students s LEFT JOIN participation p ON s.StudentID = p.StudentID 
WHERE p.CourseID IS NULL

UNION ALL

SELECT 'Course' AS type, c.CourseID, c.CourseName 
FROM courses c LEFT JOIN participation p ON c.CourseID = p.CourseID
WHERE p.StudentID IS NULL

ORDER BY type, Name

demo on dbfiddle.uk

答案 1 :(得分:1)

您可以使用带有NOT EXISTS的相关子查询来检查participation表中没有记录的学生。

SELECT *
       FROM students s
       WHERE NOT EXISTS (SELECT *
                                FROM participation p
                                WHERE p.studentid = s.studentid);

与课程类似。