2009-03-04 76 views
1

我刚刚尝试在Oracle中的SELECT语句的子句中执行相关子查询,但给出了一个错误,指示我无法执行关联(大意如此:Obs.pID未被认出)。FROM列表中的Oracle相关子查询

应该这样工作吗?

FROM ml.Person Person 
    JOIN ml.Obs ON Person.pID = Obs.pId 
     JOIN (SELECT ObsMax2.pId, ObsMax2.hdId 
       , MAX(ObsMax2.obsDate) as maxDate 
       FROM ml.Obs ObsMax2 
       WHERE ObsMax2.pId = Obs.pId 
        AND ObsMax2.obsDate < {?EndDate} 
       GROUP BY ObsMax2.pId, ObsMax2.hdId) ObsMax 
      ON Obs.pId = ObsMax.pId 
       AND Obs.hdId = ObsMax.hdId 
       AND Obs.obsDate = ObsMax.maxDate 

我的解决办法似乎是使它成为一个非相关子查询,并添加标准,保持它完全横行,横行霸道,amu-- OOF对不起子查询。

我宁愿弄清楚如何正确地关联它,尽管如果可能的话 - 像子查询一样工作的视图需要永远构建。

+0

你可能想重构查询,不只是解决这个问题语法您中运行。考虑添加关于你想要完成的问题的澄清。 – Alkini 2009-03-04 19:42:56

+1

@David - “Pedant”:-) @Alan - 我只是不确定在什么程度上我应该谈论这个系统的内部。通常情况下,我会使用一个内置的视图,通过pID/hdID进行分组来获得最新的观察结果 - 但是如果它在2009年并且您正在查询2008,则会失败。 – SarekOfVulcan 2009-03-05 05:25:01

回答

4

您可以通过使用分析函数来确定每个pid和hdid的最大obsDate,从而实现查询的这一部分的意图。

这将是这样的:

select ... 
from (
     SELECT pId, 
       hdId, 
       obsDate 
       MAX(obsDate) over (partition by pId, hdId) maxDate 
     FROM ml.Obs 
     WHERE obsDate < {?EndDate} 
     ) 
where obsDate = maxDate 
/
3

FROM子句中的子查询无法引用同一FROM子句中的其他表。删除ObsMax2.pId = Obs.pId子句应该可以解决这个问题,并且从我可以看出,由于同一子句处于连接条件中,所以会给出完全相同的结果。但是,正如您所提到的,您可能遇到在子查询中拥有GROUP BY的性能问题。

从我所知道的情况来看,您试图从ml.Obs中获取个别pID/hdId记录,其中最大obsDate小于{EndDate}。在那种情况下,将子查询移到WHERE子句中可以关联它吗?例如:

select ... 
from 
    ml.Person Person 
    join ml.Obs on Person.PID = Obs.pId 
where Obs.obsDate = (
    select max(obsDate) 
    from ml.Obs Obs2 
    where Obs2.pId = Obs.pId 
     and obs2.hdId = Obs.hdId 
     and Obs2.obsDate < {EndDate}) 
+0

如果是这种情况,尤其是如果字段只是日期类型,请小心预计可能会返回多个人(由于日期重复)。 – Alkini 2009-03-04 19:39:30

0

你已经用“ml”为你的许多表添加了前缀。但并不是无处不在(例如第一次加入)。假设你需要(用于用户/权限/不管):

JOIN ml.Obs ON Person.pID = ** **毫升Obs.pId

JOIN ml.Obs OB的 ON Person.pID = Obs.pId

还有其他地方,这也是需要的。

如果不是这种情况,请将它们从您的查询中移除,因为它们无关紧要且分散注意力。