2016-12-06 36 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 
相关问题