我相信問題可能是缺少加入STUD
和LRNHIST
內嵌視圖之間謂語。
在你提供的查詢時,STUD
聯視圖是STUDENT
和ITEM
之間的笛卡爾乘積,然後將其外部連接到LRNHIST
認爲確實具有每STUD_ID
/CPNT_ID
對一個CMPL_DTE
。但由於OUTER JOIN
僅在STUD_ID
謂詞上,您還會在STUD.CPNT_ID <> LRNHST.CPNT_ID
的位置獲得匹配,提供額外的行。
你打破它,並期待在單獨的行內觀點:
對於STUD
查詢:
SELECT STUDENT.STUD_ID, ITEM.CPNT_ID FROM STUDENT
CROSS JOIN ITEM
WHERE STUDENT.STUD_ID IN (1,2,3,4)
AND ITEM.CPNT_ID IN ('a','b','c','d');
結果:
stud_id cpnt_id
1 a
1 b
1 c
1 d
2 a
2 b
2 c
2 d
... etc
所以我們希望所有這些行的最終查詢。
如果你看看LRNHST
獨立:
SELECT LEARNHIST.STUD_ID,
LEARNHIST.CPNT_ID,
MAX(LEARNHIST.COMPL_DTE) COMPL_DTE
FROM LEARNHIST
GROUP BY LEARNHIST.STUD_ID, LEARNHIST.CPNT_ID;
確實是有每stud_id-cpnt_id對只有一排(存在於learnhist
):
stud_id cpnt_id compl_dte
1 b October, 10 2016 00:00:00
1 a May, 05 2017 00:00:00
3 b February, 02 2017 00:00:00
2 c August, 08 2016 00:00:00
現在,如果你加入只使用STUD_ID
,你會得到一個May 5th
一行其中STUD
有1 - a
和LRNHST
有1 - a
,但你也將獲得一排,其中LRNHST
有1 -b
,因爲CPNT_ID
上沒有連接謂詞。如果選擇全部五列,你可以看到複製進來:
SELECT STUD.*, LRNHIST.* FROM (
SELECT STUDENT.STUD_ID, ITEM.CPNT_ID FROM STUDENT
CROSS JOIN ITEM
WHERE STUDENT.STUD_ID IN (1,2,3,4)
AND ITEM.CPNT_ID IN ('a','b','c','d')) STUD
LEFT OUTER JOIN (SELECT LEARNHIST.STUD_ID,
LEARNHIST.CPNT_ID,
MAX(LEARNHIST.COMPL_DTE) COMPL_DTE
FROM LEARNHIST
GROUP BY LEARNHIST.STUD_ID, LEARNHIST.CPNT_ID
) LRNHIST
ON STUD.STUD_ID = LRNHIST.STUD_ID
ORDER BY 1 ASC, 2 ASC, 3 ASC, 4 ASC, 5 ASC;
結果:
s_stud s_cpnt l_stud l_cpnt l_compl
1 a 1 a May, 05 2017 00:00:00
1 a 1 b October, 10 2016 00:00:00
1 b 1 a May, 05 2017 00:00:00
1 b 1 b October, 10 2016 00:00:00
1 c 1 a May, 05 2017 00:00:00
1 c 1 b October, 10 2016 00:00:00
1 d 1 a May, 05 2017 00:00:00
1 d 1 b October, 10 2016 00:00:00
2 a 2 c August, 08 2016 00:00:00
... etc
因爲這只是加入上stud_id
,無論是Oct
和May
記錄可以自由搭配STUD
的1-a
匹配LRNHST
的1
在其1-a
對地表和1-b
組兩者。現在
如果你CPNT_ID
加入爲好,只有LRNHST
記錄符合兩個CPNT_ID
和STUD_ID
將被退回。 (May
爲1-a
和Oct
爲1-b
)
SELECT STUD.STUD_ID, STUD.CPNT_ID, LRNHIST.COMPL_DTE FROM (
SELECT STUDENT.STUD_ID, ITEM.CPNT_ID FROM STUDENT
CROSS JOIN ITEM
WHERE STUDENT.STUD_ID IN (1,2,3,4)
AND ITEM.CPNT_ID IN ('a','b','c','d')) STUD
LEFT OUTER JOIN (SELECT LEARNHIST.STUD_ID,
LEARNHIST.CPNT_ID,
MAX(LEARNHIST.COMPL_DTE) COMPL_DTE
FROM LEARNHIST
GROUP BY LEARNHIST.STUD_ID, LEARNHIST.CPNT_ID
) LRNHIST
ON STUD.STUD_ID = LRNHIST.STUD_ID
AND STUD.CPNT_ID = LRNHIST.CPNT_ID
ORDER BY 1 ASC, 2 ASC;
結果:
stud_id cpnt_id compl_dte
1 a May, 05 2017 00:00:00
1 b October, 10 2016 00:00:00
1 c (null)
1 d (null)
2 a (null)
2 b (null)
2 c August, 08 2016 00:00:00
2 d (null)
... etc
現在你應該有每STUD_ID
CPNT_ID
對只有一排,用null對compl_dte
在沒有LRNHST
記錄匹配。
如果查詢需要多次連接,那麼最好有sql小提琴來幫助您測試我們的想法。嘗試在項目中使用交叉連接,並與關鍵學生ID和cpnt ID一起使用左連接。 –