java - 使用 JOIN 语句防止 SQL 查询中重复 ID

标签 java sql oracle

我正在开发一个调度系统。因此,有几个彼此相关的表以生成时间表。首先,我不确定我做的是否正确。我希望有人能帮助我。我正在使用SQL Developer

因此,当我想要生成时间表时,我必须考虑 3 个表,即 AvailabilityLecturer 和 Student。这些是表结构。

可用性

availableid  availableday   availableStart  availableEnd  presentationid(fk) lecturerID(fk) 
-----------|--------------|----------------|-------------|------------------|--------------|
 106100    |  Monday      |    12.00 PM    |   02.00 PM  |  589             |   1001       |
 106200    |  Tuesday     |    12.00 PM    |   02.00 PM  |  590             |   1001       |
 106300    |  Wednesday   |    08.00 AM    |   08.00 AM  |  591             |   1001       |
 106400    |  Thursday    |    12.00 PM    |   02.00 PM  |  592             |   1001       |
 106500    |  Monday      |    12.00 PM    |   02.00 PM  |  589             |   1004       |
 106600    |  Tuesday     |    12.00 PM    |   02.00 PM  |  590             |   1004       |
 106700    |  Wednesday   |    08.00 AM    |   08.00 AM  |  591             |   1004       |
 106800    |  Thursday    |    12.00 PM    |   12.00 PM  |  592             |   1004       |

讲师:

lecturerID | lecturerFullname
-----------------------------
    1001   |     ABC
    1004   |     DEF

学生:

Studentid | studentName  |  lecturerid (supervisor)
---------------------------------------------------
    1     |     John     |     1001
    2     |    Martha    |     1001
    3     |     Kelly    |     1001
    4     |      Don     |     1001
    5     |     Sue      |     1001

在这里,lecturerID 扮演两个角色。 student 表中的一个被指定为主管。为了生成时间表,使用 lecturerID 指定另一位讲师作为主考人。

我已经完成查询了。假设1001讲师手下的学生将由1004讲师进行考核。

SELECT DISTINCT stud.studentID, stud.studentName, T1.availableID,
T2.availableID,
T1.availableDay,
T2.availableDay,
T1.availableEnd,
T2.availableEnd,
T1.presentationID,
T2.presentationID,
T1.lecturerID SUPERVISOR,
T2.lecturerID EXAMINER
FROM availability T1 
JOIN availability T2 ON T1.PRESENTATIONID = T2.PRESENTATIONID
JOIN student stud ON stud.LECTURERID = T1.LECTURERID
where T2.lecturerID='1004'
AND stud.lecturerID ='1001'
AND T1.LECTURERID <> T2.LECTURERID;

由于讲师有 4 个 availabilityID,我的结果是所有学生都迭代了四次。像这样的事情:

Studentid | studentName  |  supervisor | examiner    | availableID
---------------------------------------------------
    1     |     John     |     1001    | 1004        |   106100
    1     |     John     |     1001    | 1004        |   106200   
    1     |     John     |     1001    | 1004        |   106300
    1     |     John     |     1001    | 1004        |   106400
    2     |    Martha    |     1001    | 1004        |   106100
    2     |    Martha    |     1001    | 1004        |   106200
    2     |    Martha    |     1001    | 1004...     |   106300
    2     |    Martha    |     1001 
    3     |     Kelly    |     1001 ( and so on to 20 rows ...)
    4     |      Don     |     1001
    5     |     Sue      |     1001

但是,我希望显示的结果是这样的(如果可能的话):

Studentid | studentName  |  supervisor | examiner    | availableID
----------------------------------------------------------------
    1     |     John     |     1001    | 1004        |   106100
    2     |    Martha    |     1001    | 1004        |   106200
    3     |     Kelly    |     1001    | 1004        |   106300
    4     |      Don     |     1001    | 1004        |   106400

这个可以实现吗?每个学生都有不同的 availableID,如果重复,则不会显示该行。如何修复我的查询?我尝试过 GROUP BY、Min()、DISTINCT 等...但它们不起作用。

当前查询 (26/4/16):

SELECT DISTINCT stud.studentID, stud.studentName, T1.availableID,
T2.availableID,
T1.availableDay,
T2.availableDay,
T1.availableEnd,
T2.availableEnd,
T1.presentationID,
T2.presentationID,
T1.lecturerID SUPERVISOR,
T2.lecturerID EXAMINER
FROM availability T1 
JOIN availability T2 ON T1.PRESENTATIONID = T2.PRESENTATIONID
JOIN student stud ON stud.lecturerID = t1.lecturerID;
WITH cteStudent AS (
  SELECT StudentID, StudentName,lecturerID,
         ROW_NUMBER() OVER (ORDER BY StudentID ASC) srn
  FROM Student
),
     cteAvailable AS (
  SELECT lecturerID, AvailableId,
         ROW_NUMBER() OVER (ORDER BY AvailableId ASC) lrn
  FROM availability
 )
SELECT s.studentID, s.studentName, l.lecturerID,availableID
FROM cteStudent s
JOIN cteAvailable l
  ON s.lecturerID=l.lecturerID
AND s.srn=l.lrn

我说得对吗?我获取了 80 行,但获取了 0 行...问题是什么?哈哈

最佳答案

您希望学生与讲师的空闲空位一对一加入,并且两个学生不能共享同一个空位。

您可以使用 ROW_NUMBER 将学生 1 链接到空闲时间 1、2 到 2、3 到 3 等。

这是一个伪代码示例。您需要将此处使用的技术应用到您的实际查询中。

WITH cteStudent AS (
  SELECT StudentID, Name, Class, 
         ROW_NUMBER() OVER (ORDER BY StudentID ASC) srn
  FROM Students
  WHERE SomeCondition='true'
),
     cteLecturer AS (
  SELECT TeacherID, Name, Class, AvailableId
         ROW_NUMBER() OVER (ORDER BY AvailableId ASC) lrn
  FROM Teachers
  WHERE SomeCondition='true'
 )
SELECT DesiredColumns
FROM cteStudent s
JOIN cteLecturer l
  ON s.Class=l.Class
  AND s.srn=l.lrn

编辑:

这是您最新查询中的问题 (26/4/16)

JOIN cteAvailable l
  ON s.lecturerID=l.lecturerID
  AND s.srn=l.lrn
where l.lecturerID='1004'
AND s.lecturerID ='1001'

您正在加入 LecturerID,因此它们必须相同,但是您的 WHERE 子句其中一个为 1004,另一个为 1001,因此它们永远不会相同。这就是为什么你得到 0 行。

关于java - 使用 JOIN 语句防止 SQL 查询中重复 ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36865307/

相关文章:

xml - 子选择中的 oracle xmlcast(xmlquery)

java - 为什么java不支持动态变量调度

java - 打印出对象数组

mysql - 如何使用包含总和和计数的 select 来触发 MySQL?

mysql - 如何合并两个表 A 和 B,但 B 缺少一列,而结果应该包含所有列?

sql - 我们可以在单个 sql 中包含多个 "WITH AS"- Oracle SQL

java - toString 包含对象的数组列表

java - 构建第一个应用程序教程按钮不起作用

MySQL索引几乎不能加速简单查询

java - 提交之前查看 Oracle session 中的所有 DML 更改