2016-12-06 35 views
1

我需要構建一份報告以顯示每個員工(主要查詢)以及每個測試的日期和/或結果,併爲每個測試列分別顯示一列測試。我想我的查詢的結果是這樣的:需要多個子查詢,分別返回每個記錄中的所有記錄

FName LName  TB Date  TB Result XrayDate 
-------------------------------------------------- 

Bob Jones  10/1/2016 P   10/1/2016 
       9/1/2015 P   8/1/2015 
       9/15/2014 N   7/1/2014 
       8/3/2013 N 
       10/1/2012 Q 
       9/4/2011 P 
       8/16/2010 P 

下面是SQL我現在有,與子查詢在我FROM語句,在TB日期/結果拉和XRayDate,但結果乘以一次我爲XRayDate添加第二個子查詢,給我21結果,而不是總共7行數據。

EMPLOYEE.FLDLNAME, 
EMPLOYEE.FLDFNAME, 
EMPLOYEE.FLDREC_NUM, 
TUBER.FLDDATE as "TUBER Date", 
TUBER.FLDCLASS as "TUBER Result", 
XRayDate.FLDDATE as "XRay Date" 
FROM EMPLOYEE EMPLOYEE 
LEFT OUTER JOIN 
(SELECT TUBER.FLDDATE, TUBER.FLDCLASS, TUBER.FLDEMPLOYEE 
FROM TUBER TUBER) TUBER 
ON EMPLOYEE.FLDREC_NUM = TUBER.FLDEMPLOYEE 
LEFT OUTER JOIN 
(SELECT PHYSLOG.FLDDATE, PHYSLOG.FLDTYPE,PHYSLOG.FLDEMPLOYEE 
FROM PHYSLOG PHYSLOG 
WHERE PHYSLOG.FLDTYPE = 'CXR') XrayDate 
ON EMPLOYEE.FLDREC_NUM = XrayDate.FLDEMPLOYEE `EMPLOYEE.FLDLNAME 

下面是使用SQL上述結果的一個樣本:

Fname LName TB Date  TB Result Xray Date 
--------------------------------------- 

Bob Jones 10/1/2016 P   10/1/2016 
      10/1/2016 P   8/1/2015 
      10/1/2016 P   7/1/2014 
      9/1/2015 P   10/1/2016 
      9/1/2015 P   8/1/2015 
      9/1/2015 P   7/1/2014 
      9/15/2015 N   10/1/2016 
      9/15/2015 N   8/1/2015 
      9/15/2015 N   7/1/2014 
      8/3/2013 N   10/1/2016 
      8/3/2013 N   8/1/2015 
      8/3/2013 N   7/1/2014 
      10/1/2012 Q   10/1/2016 
      10/1/2012 Q   8/1/2015 
      10/1/2012 Q   7/1/2014 
      9/4/2011 P   10/1/2016 
      9/4/2011 P   8/1/2015 
      9/4/2011 P   7/1/2014 
      8/16/2010 P   10/1/2016 
      8/16/2010 P   8/1/2015 
      8/16/2010 P   7/1/2014 

我新,以在SQL Developer中的子查詢,讓您的建議/反饋是受歡迎的。

+0

在你的第二個子查詢中嘗試分組。 SELECT MAX(PHYSLOG.FLDDATE)FLDDATE,PHYSLOG.FLDTYPE,PHYSLOG.FLDEMPLOYEE FROM PHYSLOG PHYSLOG WHERE PHYSLOG.FLDTYPE = 'CXR' \t組由PHYSLOG.FLDTYPE,PHYSLOG.FLDEMPLOYEE – Kostya

+1

如果上述建議沒有幫助試試看看[這個問題](http://meta.stackoverflow.com/questions/333952/why-should-i-provide-an-mcve-for-what-seems-to-me-to-be-a - 非常 - 簡單的SQL查詢)。它解釋了試圖回答問題時,有用的樣本數據的可能性。 –

+0

別名的概念是爲對象提供不同的名稱。這通常是爲了輸入較少。用與表格相同的名稱來替換表格只是額外的輸入練習。這與提供清晰度相反。你必須看兩遍才能意識到它在做什麼。並且在你的子查詢中不要選擇你沒有使用的列(你不必選擇能夠在連接中使用它的列)。 –

回答

0

Row_number測試和完全加入rn。十字/外應用的結果,這樣的

SELECT 
    EMPLOYEE.FLDLNAME, 
    EMPLOYEE.FLDFNAME, 
    EMPLOYEE.FLDREC_NUM, 
    TUBER_FLDDATE as "TUBER Date", 
    TUBER_FLDCLASS as "TUBER Result", 
    XRayDate_FLDDATE as "XRay Date" 
FROM EMPLOYEE EMPLOYEE 
CROSS APPLY 
    (SELECT TUBER_FLDDATE = TUBER.FLDDATE, 
      TUBER_FLDCLASS = TUBER.FLDCLASS, 
      XrayDate_FLDDATE = XrayDate.FLDDATE 
     FROM (SELECT rn = row_number() over(order by TUBER.FLDDATE), TUBER.FLDDATE, TUBER.FLDCLASS 
      FROM TUBER 
      WHERE EMPLOYEE.FLDREC_NUM = TUBER.FLDEMPLOYEE) TUBER 
     FULL OUTER JOIN (SELECT rn = row_number() over(order by PHYSLOG.FLDDATE), PHYSLOG.FLDDATE 
      FROM PHYSLOG 
      WHERE PHYSLOG.FLDTYPE = 'CXR' AND EMPLOYEE.FLDREC_NUM = PHYSLOG.FLDEMPLOYEE) XrayDate 
       ON XrayDate.rn=TUBER.rn 
    ) tests 
+0

這太棒了!並根據需要返回!謝謝! –

+0

還有一個問題。我必須爲此添加大約8個子查詢,所有子查詢都具有WHERE EMPLOYEE.FLDREC_NUM =(table).FLDEMPLOYEE關係。新的將使用與XRayDate相同的表格,但Type = TBQEST,並且需要最大日期與所有日期。你能解釋一下,一旦我創建另一個完全外部聯接,「ON」子句應該是什麼樣子? (例如,新的子查詢別名將是TBQESTDate。這是TBQESTDate.rn =?。rn還是別的)?謝謝 –

+0

你需要全加入第三個表'coalesce(XrayDate.rn,TUBER.rn)= TBQESTDate.rn'。等等,對於n次使用合併(.rn,.. .rn)= .rn – Serg

0

可以顯著通過簡化查詢:

  • 不走樣表與他們已經擁有(在評論上述由Sean Lange提到)的同名。例如,說明FROM EMPLOYEE EMPLOYEE沒有意義,因爲您可以參考標識爲EMPLOYEEEMPLOYEE表。相反,請嘗試使用簡寫標識符來使查詢更快,更易於閱讀。
  • JOIN不是使用子查詢,除非你真的需要

因此,例如:

SELECT e.FLDLNAME, 
     e.FLDFNAME, 
     e.FLDREC_NUM, 
     t.FLDDATE AS [TUBER Date], 
     t.FLDCLASS AS [TUBER Result], 
     x.FLDDATE AS [XRay Date] 
FROM EMPLOYEE e 
LEFT OUTER JOIN TUBER t ON e.FLDREC_NUM = t.FLDEMPLOYEE 
LEFT OUTER JOIN PHYSLOG x ON e.FLDREC_NUM = x.FLDEMPLOYEE 
WHERE x.FLDTYPE = 'CXR' 

應該給你同樣的結果在你的查詢有問題。現在

,如果你當JOIN s的包括比你沒有他們返回的記錄數量更多,這表明有兩種:

  • TUBER表的多個記錄的每個值FLDEMPLOYEE
  • PHYSLOG表中的多個記錄每個值爲FLDEMPLOYEE
  • 或兩者都有!

您可以通過從這些表返回更多的詳細檢查此:

SELECT e.FLDLNAME, 
     e.FLDFNAME, 
     e.FLDREC_NUM, 
     t.*, 
     x.* 
FROM EMPLOYEE e 
LEFT OUTER JOIN TUBER t ON e.FLDREC_NUM = t.FLDEMPLOYEE 
LEFT OUTER JOIN PHYSLOG x ON e.FLDREC_NUM = x.FLDEMPLOYEE 
WHERE x.FLDTYPE = 'CXR' 

我建議你選擇一些相關的領域,而不是實際使用t.*x.*,但我不知道你的表結構,因爲你沒有提供它。

如果您發現FLDEMPLOYEE的每個值的JOIN ed表中有多個記錄,那麼您需要決定如何處理此問題,最有可能的方法是對數據進一步過濾在WHERE子句中,或者通過使用GROUP BY子句。例如,如果您意識到TUBER表中有多個記錄,每個值爲FLDEMPLOYEE,則可能會看到您可以過濾到僅使用TUBER表中某些其他字段感興趣的記錄:

SELECT e.FLDLNAME, 
     e.FLDFNAME, 
     e.FLDREC_NUM, 
     t.FLDDATE AS [TUBER Date], 
     t.FLDCLASS AS [TUBER Result], 
     x.FLDDATE AS [XRay Date] 
FROM EMPLOYEE e 
LEFT OUTER JOIN TUBER t ON e.FLDREC_NUM = t.FLDEMPLOYEE 
LEFT OUTER JOIN PHYSLOG x ON e.FLDREC_NUM = x.FLDEMPLOYEE 
WHERE x.FLDTYPE = 'CXR' 
AND t.OtherField = 'SomeValue' 

只要你確定你申請任何額外的過濾從TUBER表每FLDEMPLOYEE值(總是會)將只返回一個記錄,這應該能正常運行。

另外,例如,如果你認識到,有在PHYSLOG表的FLDEMPLOYEE每個值的多個記錄,您可能希望只與最近的日期在FLDDATE返回字段的記錄:

SELECT e.FLDLNAME, 
     e.FLDFNAME, 
     e.FLDREC_NUM, 
     t.FLDDATE AS [TUBER Date], 
     t.FLDCLASS AS [TUBER Result], 
     MAX(x.FLDDATE) AS [Most Recent XRay Date] 
FROM EMPLOYEE e 
LEFT OUTER JOIN TUBER t ON e.FLDREC_NUM = t.FLDEMPLOYEE 
LEFT OUTER JOIN PHYSLOG x ON e.FLDREC_NUM = x.FLDEMPLOYEE 
WHERE x.FLDTYPE = 'CXR' 
GROUP BY e.FLDLNAME, 
     e.FLDFNAME, 
     e.FLDREC_NUM, 
     t.FLDDATE, 
     t.FLDCLASS 
相關問題