我有以下表格
1.student(student_id数据,student_name)
+------------+--------------+-----------+
| student_id | Student_name | class |
+------------+--------------+-----------+
| 1 | A | 5TH GRADE |
| 2 | B | 5TH GRADE |
| 3 | C | 5TH GRADE |
+------------+--------------+-----------+
2.student_subject_link(student_id数据,subject_id)
+------------+------------+
| student_id | subject_id |
+------------+------------+
| 1 | 400 |
| 2 | 401 |
| 1 | 401 |
| 2 | 403 |
| 3 | 400 |
| 3 | 401 |
+------------+------------+
3.subject(subject_id,SUBJECT_NAME),
+------------+-----------------+
| subject_id | subject_name |
+------------+-----------------+
| 400 | MATHS |
| 401 | PHYSICS |
| 402 | CHEMISTRY |
| 403 | COMPUTERSCIENCE |
| 404 | ENGLISH |
+------------+-----------------+
4.student_file(student_id数据,的file_id,FILE_NAME,file_uploaded_by,file_updated_by)
+------------+---------+-----------+-----------------+-----------------+
| STUDENT_ID | FILE_ID | FILE_NAME | FILE_CREATED_BY | FILE_UPDATED_BY |
+------------+---------+-----------+-----------------+-----------------+
| 1 | 500 | FILEA.TXT | STAFF1 | STAFF2 |
| 2 | 501 | FILEB.TXT | STAFF2 | STAFF2 |
| 3 | 502 | FILEC.TXT | STAFF3 | STAFF2 |
+------------+---------+-----------+-----------------+-----------------+
5.staff(staff_id,staff_name)student_file和staff表由staff_id.file_uploaded_by链接,file_created_by有staff_id。
+----------+------------+
| STAFF_ID | STAFF_NAME |
+----------+------------+
| STAFF1 | XX |
| STAFF2 | YY |
| STAFF3 | ZZ |
+----------+------------+
我需要得到以下输出。是否有可能在单个查询中实现这一点,或者我必须使用多个查询(一个用于获取主题ID,另一个用于文件详细信息。我在弹簧Web应用程序中使用它。你能告诉我最好的方法吗?实现这一目标。
我想加入所有这些表来接受student_name,他注册的主题列表(逗号分隔字段),file_name,文件创建者(员工表中的员工姓名),文件更新者(员工表中的员工姓名)
+--------------+-------------------------+-----------+-----------------+-----------------+
| STUDENT_NAME | SUBJECT | FILE_NAME | FILE_CREATED_BY | FILE_UPDATED_BY |
+--------------+-------------------------+-----------+-----------------+-----------------+
| 1 | MATHS,PHYSICS | FILEA.TXT | XX | YY |
| 2 | PHYSICS,COMPUTERSCIENCE | FILEB.TXT | YY | YY |
| 3 | MATHS,PHYSICS | FILEC.TXT | ZZ | YY |
+--------------+-------------------------+-----------+-----------------+-----------------+
答案 0 :(得分:2)
试试这个。
WITH sub AS
(SELECT student_id,
LISTAGG(subject_name, ',') WITHIN
GROUP (
ORDER BY subject_id) SUBJECT
FROM
(SELECT DISTINCT sbl.student_id,
sb.subject_id,
subject_name
FROM student_subject_link sbl
JOIN subject sb ON sb.subject_id = sbl.subject_id )
GROUP BY student_id )
SELECT stu.student_name,
MAX(sub.subject) SUBJECT,
MAX(sf.file_name) FILE_NAME,
MAX(
(SELECT stf.staff_name
FROM staff stf
WHERE stf.STAFF_ID = sf.FILE_CREATED_BY )) FILE_CREATED_BY,
MAX(
(SELECT stf.staff_name
FROM staff stf
WHERE stf.STAFF_ID = sf.FILE_UPDATED_BY )) FILE_UPDATED_BY
FROM student stu
JOIN sub ON sub.student_id = stu.student_id
JOIN student_file sf ON sf.student_id = stu.student_id
GROUP BY stu.student_name;
编辑:
解释(OP请求):student_subject_link
和student
与subject_id相关。但由于关系是多对多的,因此登记主题的连接操作在一个单独的with子句中进行,并且不包括在涉及主表的连接中以避免混淆。 LISTAGG
函数连接组中的元素。Distinct
用于避免因连接而形成的重复项。 with
子句帮助我们构建一个可以重用的内联视图,就像它是一个表一样。
在select子句中,由于我们需要按student_name进行分组,因此所有其他值的MAX
都是该组所需的值。 select中的相关子查询用于获取相应的staff_name
,因为由于一对多关系,它不能被内连接。