2

私はこの SQL の問題に約 2 日間取り組んできましたが、問題の解決に非常に近づいていると思われますが、完全に機能する解決策を見つけることができないようです。

私がやろうとしているのは、application_infoapplication_statusという 2 つのテーブルを選択的に結合することです。これらのテーブルは、オープン アクセス ジャーナル記事の資金調達リクエストに関する情報を格納するために使用されます。

application_info申請者に関する一般的な情報がありApplication_ID、キー フィールドと呼ばれる自動インデックス フィールドを使用します。application_status申請のステータス (受理、審査中、資金提供、却下、撤回など) およびジャーナル記事のステータス (提出、受理、再提出、公開、または却下) に関する継続的な情報を追跡するために使用され、両方が含まれます。ステータス テキストとステータス日付フィールドとともに呼び出されるApplication_IDフィールドと自動インデックスフィールド。Status_ID

アプリケーション、記事、および資金調達ステータスの変更の実行中のログを保持したいので、更新された値で既存の行を上書きしたくはありませんapplication_statusが、代わりに最新のステータス値のみを表示したいと考えています。アプリケーションは最終的に複数のステータス変更を持つため、各アプリケーション ID に対して 1 つの行のみが返されるように、アプリケーション データへのステータス データの内部結合に何らかの制限を適用する必要があります。

現在エラーをスローしているクエリで私がやろうとしていることの例を次に示します。

-- simplified example
SELECT 
application_info.*,
artstatus.Status_ID AS Article_Status_ID,
artstatus.Application_ID AS Article_Application_ID,
artstatus.Status_State_Date AS Article_Status_State_Date,
artstatus.Status_State_Text AS Article_Status_State_Text
FROM application_info
LEFT JOIN (
    SELECT 
    Status_ID,
    Application_ID,
    Status_State_Text,
    Status_State_Date,
    Status_State_InitiatedBy,
    Status_State_ChangebBy,
    Status_State_Notes
    FROM application_status 
    WHERE Status_State_Text LIKE 'Article Status%'
    AND Application_ID = application_info.Application_ID -- how to pass the current application_info.Application_ID from the ON clause to here?
    -- and Application_ID = 29 -- this would be an option for specific IDs, but not an option for getting a complete list of application IDs with status
    -- GROUP BY Application_ID -- reduces the sub query to 1 row (Yeah!) but returns the first row encountered before the ORDER BY comes into play
    ORDER BY Status_ID DESC
    -- a GROUP BY after the ORDER BY might resolve the issue if we could do a sort first
    LIMIT 1 -- only want to get the first (most recent) row, only works correctly if passing an Application_ID
) AS artstatus
ON application_info.Application_ID = artstatus.Application_ID
-- WHERE application_info.Application_ID = 29 -- need to get all IDs with statu values as well as for specific ID requests
;

AND Application_ID = application_info.Application_IDサブクエリのand の部分と を削除するとLIMIT、選択は機能しますが、特定のアプリケーション ID のすべてのステータスの行が返されます。MIN/演算子をいじってみましたが、動作時にテーブルMAXから予測できない行が返されることに気付きました。application_status

また、結合のセクションでサブ選択を実行しようとしましたがON、最終結果が常に返す必要があるため、それを機能させる方法がわかりませんApplication_ID(両方Application_IDStatus_IDも返して使用できますか?)。

これを意図したとおりに機能させる方法に関するヒントはありますか? これもできますか?

さらに編集: 以下の作業クエリ。重要なのは、結合内のサブクエリを 1 レベル深く移動し、1 つのステータス ID だけを返すことでした。

-- simplified example (now working)
SELECT 
application_info.*,
artstatus.Status_ID AS Article_Status_ID,
artstatus.Application_ID AS Article_Application_ID,
artstatus.Status_State_Date AS Article_Status_State_Date,
artstatus.Status_State_Text AS Article_Status_State_Text
FROM application_info
LEFT JOIN (
    SELECT 
    Status_ID,
    Application_ID,
    Status_State_Text,
    Status_State_Date,
    Status_State_InitiatedBy,
    Status_State_ChangebBy,
    Status_State_Notes
    FROM application_status AS artstatus_int
    WHERE 
    -- sub query moved one level deeper so current join Application_ID can be passed
    -- order by and limit can now be used
    Status_ID = (
        SELECT status_ID FROM application_status WHERE Application_ID = artstatus_int.Application_ID
        AND status_State_Text LIKE 'Article Status%'
        ORDER BY Status_ID DESC
        LIMIT 1
    )
    ORDER BY Application_ID, Status_ID DESC
    -- no need for GROUP BY or LIMIT here because only one row is returned per Application_ID
) AS artstatus
ON application_info.Application_ID = artstatus.Application_ID
-- WHERE application_info.Application_ID = 29 -- works for specific application ID as well

-- more LEFT JOINS follow
;
4

1 に答える 1

2

from句に相関サブクエリを含めることはできません。

代わりにこのアイデアを試してください:

select <whatever>
from (select a.*,
             (select max(status_id) as maxstatusid
              from application_status aps
              where aps.application_id = a.application_id
             ) as maxstatusid
      from application
     ) left outer join
     application_status aps
     on aps.status_id = a.maxstatusid
. . .

つまり、相関サブクエリをselect句に入れて、最新のステータスを取得します。次に、これをステータステーブルに結合して、他の情報を取得します。そして、他の詳細でクエリを終了します。

あなたはSQLスキルにかなり精通しているように見えるので、クエリ全体を書き直す必要はないようです。

于 2012-08-08T16:31:08.907 に答える