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

时间:2016-04-26 12:42:17

标签: java sql oracle

我正在研究一个调度系统。因此,存在若干彼此相关的表以便生成调度。首先,我不确定我的做法是否正确。我希望有人可以帮助我。我正在使用 SQL开发人员

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

Availability

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       |

lecturer

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

Student

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行...有什么问题?哈哈

1 个答案:

答案 0 :(得分:0)

您希望学生与Lecturer的可用性插槽进行一对一的加入,并且没有两个学生可以共享同一个插槽。

您可以使用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'

你正在加入讲座ID,所以它们必须是相同的,但是你的WHERE子句在一个中有1004,在另一个中有1001,所以它们永远不会是相同的。这就是你获得0行的原因。