web-dev-qa-db-ja.com

rownumへの左外部結合のためのOracle SQL = 1別のクエリ?

バックグラウンド

多くのテーブルを結合するクエリがあります。その主なものはワークオーダーテーブルです。

また、すべてのワークオーダーのすべてのステータスを格納するWOStatusHistoryというテーブルがあります。

2つの間の左外部結合の図は次のようになります。

 +------------+           +----------------+
 |Workorder   |           |WOStatusHistory |
 |------------| LO JOIN   |----------------|
 |WONum       |+--------->|WONum           |
 |Location    |           |Status          |
 |Description |           |ChangeDate      |
 |...         |           +----------------+
 +------------+

ゴール

特定の作業指示書のステータスが完了した最新の日付を返す必要があります(人間の言葉で「この作業指示書が最後に完了した時間を教えてください」)。

これまでのプロセス

トップレコードを返さないこのためのSQLは簡単です。

SELECT *
FROM   WORKORDER
       LEFT OUTER JOIN (SELECT WONUM        AS STATUSWONUM
                               , STATUS     AS STATUS
                               , CHANGEDATE AS STATUSCHANGEDATE
                        FROM   WOSTATUSHISTORY
                        WHERE  STATUS = 'COMP'
                        ORDER  BY CHANGEDATE DESC)LASTCOMPLETE
         ON ( WORKORDER.WONUM = LASTCOMPLETE.STATUSWONUM ) 

;

問題

ただし、最新の日付のみを返すために、適切なタイミングでrownum = 1を取得する方法を理解するのに苦労しています。

私の唯一のオプションは(私が間違っていると思いますが)です:

  • Wostatushistoryクエリ内にrownum = 1を配置します。これは、リンクされる前に結果を制限するようです。
  • 結合の外側にrownum = 1を配置します。返されたセットの合計から1つのレコードしか得られないため、これは目的に役立ちません。

あなたが与えることができるあらゆる助けを前もってありがとう!何でもはっきりさせてください。

3
SeanKilleen

基本的に、ここで探しているのが同じ場合、同じフィルターを使用して、最大日付を取得するだけでよいと思います。すでにSTATUS(= COMP)とWONUM(JOIN)を持っています。このテーブルのレコード全体が必要であり、これよりも複雑な場合は、ロジックによるオーバー/パーティション化を使用したOracleインライン分析関数で最大日付でフィルタリングすることをお勧めします。

SELECT *
FROM   WORKORDER
       LEFT OUTER JOIN (SELECT WONUM AS STATUSWONUM 
                               , STATUS AS STATUS
                               , MAX(CHANGEDATE) AS STATUSCHANGEDATE
                        FROM   WOSTATUSHISTORY
                        WHERE  STATUS = 'COMP'
                        GROUP  BY WONUM, STATUS)LASTCOMPLETE
         ON ( WORKORDER.WONUM = LASTCOMPLETE.STATUSWONUM ) 

;
3
REW