如何在oracle中加入两个以上的连接级别

时间:2017-12-03 15:56:19

标签: oracle stored-procedures oracle11g

我有以下表格

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              |
+--------------+-------------------------+-----------+-----------------+-----------------+

1 个答案:

答案 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_linkstudent与subject_id相关。但由于关系是多对多的,因此登记主题的连接操作在一个单独的with子句中进行,并且不包括在涉及主表的连接中以避免混淆。 LISTAGG函数连接组中的元素。Distinct用于避免因连接而形成的重复项。 with子句帮助我们构建一个可以重用的内联视图,就像它是一个表一样。

在select子句中,由于我们需要按student_name进行分组,因此所有其他值的MAX都是该组所需的值。 select中的相关子查询用于获取相应的staff_name,因为由于一对多关系,它不能被内连接。