2009-03-04 14 views
1

OracleのSELECT文のFROM句で相関サブクエリを実行しようとしましたが、相関関係ができないことを示すエラーが表示されました(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 

私の回避策は非相関サブクエリにするように見える、と OOF申し訳amu--、逆上、逆上完全に実行されているからそれを保つサブクエリに基準を追加します。

可能であれば、それを適切に相関させる方法を理解したいと思います。サブクエリのように機能するビューは永遠に構築されます。

+0

。あなたが達成しようとしていることについての質問に明確化を加えることを検討してください。 – Alkini

+1

@David - "Pedant" :-) @Alan - 私はこのシステムの内部についてどの程度話しているのか分かりません。通常、私は、最近の観測結果を得るためにpID/hdIDによるグループ化を行うビルトインビューを使用しますが、2009年で2008年にクエリを実行している場合は失敗します。 – SarekOfVulcan

答えて

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 
/
+0

このバージョンの説明計画は、私が思いついたものよりも少し上手く、より速く感じています。私はこれらに前もって走っていなかった - ありがとう! – SarekOfVulcan

+0

問題はありません。分析関数は非常にクールです。 –

+1

あなたは私にPARTITION BYの使い方を教えてくれて、私の問題を解決しました。 –

3

FROM句内のサブクエリは、同じFROM句の他のテーブルを参照することはできません。 ObsMax2.pId = Obs.pId句を削除すると問題が解決するはずです。同じ節が結合条件にあるため、同じ結果が得られます。しかし、あなたが言及しているように、サブクエリにGROUP BYを持つことでパフォーマンスの問題に遭遇するかもしれません。

私が知ることから、個々のpID/hdIdレコードをml.Obsから取得し、最大のobsDateが{EndDate}未満であることを確認しようとしています。その場合、WHERE句にサブクエリを関連付けることができますか?たとえば、

+0

これが当てはまる場合、特にフィールドは型の日付に過ぎないので、重複した日付のために複数の人が返されることがあることに注意してください。 – Alkini

+0

はい、(pId、hdId、obsDate)の組み合わせが一意でない場合は、(pId、hdId)ペアごとに複数のレコードを取得できます。私は元のクエリが同じ問題を抱えていると思います。 –

+0

これは、EMR(医療記録)システムのクエリです。 pIdはPersonIdであり、hdIdは医学的観察(BP、Pulse、LDLなど)を識別します。したがって、pid/hdid/dateの複製について心配する必要はありません。 – SarekOfVulcan

0

テーブルの先頭に「ml」が付いています。どこにでもあるわけではありません(たとえば、最初の結合)。あなたは(ユーザーのために/権限/何でも)ことを必要とすると仮定:

はPerson.pID = ** mlのON ml.Obsを登録しよう** Obs.pId

または

がml.ObsにOBSを登録しよう。 ON Person.pID = Obs.pId

これが必要な場所もあります。

これが当てはまらない場合は、無関係で気を散らすので、クエリから削除してください。

関連する問題