从四个相关的 table 中获取 table 中不存在的数据

Fetch Data that do not exist in a table from four related tables

我的数据库中有四个相互关联的表。

document_category(document_category_id, document_category)
document_type(document_type_id, document_category.document_category_id, document_type)
student(student_id, f_name, l_name, ...other_columns)
student_document(id, student.student_id, document_type.document_type_id, file)

document_category, document_type, student and student_document

Table student_document 存储上传的文档。 我想要一个查询来显示学生未上传的文档列表。

我试过了

(SELECT document_type FROM document_category JOIN document_type ON document_category.document_category_id = document_type.document_category_id
) LEFT JOIN(SELECT FILE FROM student_document JOIN student ON student.student_id = student_document.student_id) ON document_type.document_type_id = student_document.document_type_id

我得到一个错误

#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'LEFT JOIN(
    SELECT FILE
FROM
    student_document
JOIN student ON stud...' at line 8

我也试过这个

SELECT * FROM document_type A LEFT JOIN student_document B ON A.document_type_id = B.document_type_id WHERE B.document_type_id is null

这给了我 Results,但我无法获取特定学生的数据。

我试的最后一个是

SELECT student.email, student_document.file, document_type, document_category FROM student, document_type, document_category, student_document WHERE NOT EXISTS(SELECT * FROM student_document WHERE student_id = 'M054/T19' AND document_type_id ='20') AND student.student_id = student_document.student_id AND document_type.document_category_id = document_category.document_category_id

这给了我 Undesirable,但这不是我想要的。

DECLARE @dc TABLE(dc_id Int, ctg VarChar(30));
INSERT INTO @dc VALUES (3,'Admission'),(5,'Payment');
DECLARE @dt TABLE (dt_id Int, dc_id Int, dtp VarChar(30));
INSERT INTO @dt VALUES (27,3, 'Admission Offer'),
(28,3,'Acceptance Letter');
DECLARE @s TABLE(s_id Int, f_name VarChar(30))
INSERT INTO @s VALUES (1, 'Marco'), (2, 'Mike')
DECLARE @sd TABLE (sd_id Int, s_id Int, dt_id Int, [file] VarChar(30))
INSERT INTO @sd VALUES (10,1,27,'File01');

SELECT dc.dc_id, ctg, dt.dt_id, dt.dtp, s.s_id, f_name FROM @dc dc 
JOIN @dt dt ON dc.dc_id = dt.dc_id
CROSS APPLY @s s

-- All expected documents
dc_id   ctg dt_id   dtp s_id    f_name
3   Admission   27  Admission Offer 1   Marco
3   Admission   27  Admission Offer 2   Mike
3   Admission   28  Acceptance Letter   1   Marco
3   Admission   28  Acceptance Letter   2   Mike

-- Provided documents
    SELECT dc.dc_id, ctg, dt.dt_id, dt.dtp, s.s_id, f_name FROM @dc dc 
    JOIN @dt dt ON dc.dc_id = dt.dc_id
    JOIN @sd sd ON sd.dt_id = dt.dt_id
    JOIN @s s ON s.s_id = sd.s_id 

dc_id   ctg dt_id   dtp s_id    f_name
3   Admission   27  Admission Offer 1   Marco

-- Subtracting Set from Set
SELECT dc.dc_id, ctg, dt.dt_id, dt.dtp, s.s_id, f_name FROM @dc dc 
JOIN @dt dt ON dc.dc_id = dt.dc_id
CROSS APPLY @s s
EXCEPT
SELECT dc.dc_id, ctg, dt.dt_id, dt.dtp, s.s_id, f_name FROM @dc dc 
JOIN @dt dt ON dc.dc_id = dt.dc_id
JOIN @sd sd ON sd.dt_id = dt.dt_id
JOIN @s s ON s.s_id = sd.s_id 

dc_id   ctg dt_id   dtp s_id    f_name
3   Admission   27  Admission Offer 2   Mike
3   Admission   28  Acceptance Letter   1   Marco
3   Admission   28  Acceptance Letter   2   Mike

此代码运行良好。 WHERE NOT EXISTS 之前的第一个查询检索所有必需文件的列表和学生列表,这是学生必须上传的文件的详细列表。第二部分检索学生上传的文档列表。

因此查询检索了上传文档列表中不存在的所需文档列表。

SELECT sp.student_id, do.document_type_id, do.document_type 
FROM student_profile sp 
CROSS JOIN document_type do 
WHERE NOT EXISTS (SELECT sd.student_id, sd.document_type_id, d.document_type FROM student_document sd 
INNER JOIN document_type d ON sd.document_type_id = d.document_type_id 
WHERE do.document_type_id = sd.document_type_id 
AND sp.student_id = sd.student_id );