从表中选择一个字段,以获取两个不同表中的两个不同值

时间:2016-10-24 05:01:46

标签: oracle

我有四个表,如下所示.HL_STUDENT,HL_SEM1_CRS和HL_SEM2_CRS表,其中STUDENT作为主键,而HL_TITLE没有STUDENT字段,并且以课程编号(CRS_NBR)为键。

HL_STUDENT  A
HL_SEM1_CRS B
HL_SEM2_CRS C
HL_CRS_TITLE D

我需要获得学生,CRS-1,CRS1-TITLE-DESC,CRS-2,CRS2-TITLE-DESC,如下所示。我需要课程1和课程2的课程描述。

STUDENT CRS-1  CRS1-TITLE-DESC  CRS-2  CRS2-TITLE-DESC
1        25    MATH             35     HISTORY
2        35    HISTORY          25     MATH

我想通过两次使用不同的ALIAS加入HL_CRS_TITLE表来获得解决方案,如下所示。

SELECT DISTINCT A.STUDENT
               ,B.CRS_1
               ,D.CRS_TITLE_DESC
               ,C.CRS_2
               ,E.CRS_TITLE_DESC
FROM HL_STUDENT A 
LEFT JOIN HL_SEM1_CRS B ON A.STUDENT = B.STUDENT
LEFT JOIN HL_CRS_TITLE D ON D.CRS_NBR = B.CRS_1
LEFT JOIN HL_SEM2_CRS B ON A.STUDENT = B.STUDENT
LEFT JOIN HL_CRS_TITLE E ON E.CRS_NBR = B.CRS_2

您能否建议更好的方法来获得解决方案?

我正在查询ORACLE DB。

感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

据我所知,如果您在第一学期加入学生和课程并在第二学期加入课程,问题是重复的,您会看到交叉课程吗?

如果是真的,您可以在课程之间使用FULL JOIN并将其与学生和标题一起加入

SELECT DISTINCT A.STUDENT
           ,B.CRS_1
           ,D.CRS_TITLE_DESC
           ,B.CRS_2
           ,E.CRS_TITLE_DESC
FROM HL_STUDENT A 
JOIN (SELECT NVL(B1.STUDENT, B2.STUDENT) as STUDENT, B1.CRS_1, B2.CRS_2
       FROM HL_SEM1_CRS B1  
       FULL JOIN HL_SEM2_CRS B2 ON B1.STUDENT = B2.STUDENT AND B1.CRS_1 = B2.CRS_2) B ON A.STUDENT = B.STUDENT 
LEFT JOIN HL_CRS_TITLE D ON D.CRS_NBR = B.CRS_1
LEFT JOIN HL_CRS_TITLE E ON E.CRS_NBR = B.CRS_2

没有双重连接到HL_CRS_TITLE的示例。

SELECT DISTINCT A.STUDENT
           ,B.CRS_1
           ,nvl2(B.CRS_1, D.CRS_TITLE_DESC, null) as CRS_TITLE_DESC_1
           ,B.CRS_2
           ,nvl2(B.CRS_2, D.CRS_TITLE_DESC, null) as CRS_TITLE_DESC_2
FROM HL_STUDENT A 
JOIN (SELECT NVL(B1.STUDENT, B2.STUDENT) as STUDENT,nvl(B1.CRS_1, B2.CRS_2) as CRS,B1.CRS_1, B2.CRS_2
       FROM HL_SEM1_CRS B1  
       FULL JOIN HL_SEM2_CRS B2 ON B1.STUDENT = B2.STUDENT AND B1.CRS_1 = B2.CRS_2) B ON A.STUDENT = B.STUDENT 
LEFT JOIN HL_CRS_TITLE D ON D.CRS_NBR = B.CRS

答案 1 :(得分:0)

我认为您正在寻找一种方法来获取两个学期的记录的课程标题,而无需两次加入HL_CRS_TITLE。
我遇到了类似的情况,并创建了一个功能来实现这个目的。

--Function DDL
CREATE OR REPLACE FUNCTION F_GET_CRS_TITLE (IN_CRS_NBR IN NUMBER)
RETURN VARCHAR2 
RESULT_CACHE
AS
LV_CRS_TITLE_DESC VARCHAR2(100);
BEGIN
SELECT CRS_TITLE_DESC
INTO   LV_CRS_TITLE_DESC
FROM   HL_CRS_TITLE
WHERE  CRS_NBR = IN_CRS_NBR;
RETURN LV_CRS_TITLE_DESC;
EXCEPTION
WHEN NO_DATA_FOUND THEN
  RETURN 'NO_COURSE_EXISTS';
END;
/

您可以重写以下内容:

SELECT DISTINCT A.STUDENT
               ,B.CRS_1
               ,F_GET_CRS_TITLE(B.CRS_1)
               ,C.CRS_2
               ,F_GET_CRS_TITLE(C.CRS_2)
FROM HL_STUDENT A 
LEFT JOIN HL_SEM1_CRS B ON A.STUDENT = B.STUDENT
LEFT JOIN HL_SEM2_CRS C ON A.STUDENT = C.STUDENT;