2

私には2つのテーブルがあります:承認と決済です。'Settlements'には、権限への外部キー参照が含まれています。

決済には、ステータス(ERROR、ACCEPTEDなど)を含めることもできます。

このデータを考えると:

承認の決済
id id | auth_id | 状態
----- ---------------------------
111エラー
221承認済み

ACCEPTED決済レコードを持たないすべての承認を検索するSQLクエリを作成しようとしています。LEFT OUTER JOINを試しましたが、返される行が多すぎます。例えば:

SELECT * FROM authorizations a
LEFT OUTER JOIN settlements s ON a.id = s.auth_id
WHERE s.status is null OR s.status != 'ACCEPTED'

これに伴う問題は、複数の決済レコードがあり、そのうちの1つが受け入れられた場合でも、承認レコードを返すことです。または、複数のERRORレコードがある場合、許可は2回返されます。

ステータスが「承認済み」の対応する決済レコードがない単一の承認レコードのみをフェッチするにはどうすればよいですか?ストレートSQLで可能ですか、それともコードで結果をフィルタリングする必要がありますか?

4

3 に答える 3

7
SELECT  *
FROM    authorizations a
WHERE   NOT EXISTS
        (
        SELECT  NULL
        FROM    Settlements s
        WHERE   s.auth_id = a.id
                AND s.status = 'ACCEPTED'
        )
于 2009-08-10T17:28:15.250 に答える
2

試す

SELECT a.* FROM authorizations a
LEFT OUTER JOIN (SELECT S.* from settlements s1 
WHERE  s1.status = 'ACCEPTED')
ON a.id = s.auth_id
WHERE s.auth_id is null

これにより、受け入れられたすべてのレコードが選択され、そのグループに含まれていない承認が取得されます。

于 2009-08-10T17:43:47.637 に答える
0

あなたの例に基づいて、JOINをRIGHT結合に変更した場合、s.statusがnullであることを確認する必要はありません。

SQL Server 2005 以降または Oracle 9i 以降で動作します。

WITH unacceptedSettlements AS (
     SELECT s.auth_id
       FROM SETTLEMENTS s
      WHERE s.status != 'ACCEPTED'
   GROUP BY s.auth_id)
SELECT t.*
  FROM AUTHORIZATIONS t
  JOIN unacceptedSettlements us ON us.auth_id = t.auth_id

任意のデータベースの代替:

SELECT t.*
  FROM AUTHORIZATIONS t
  JOIN (SELECT s.auth_id 
         FROM SETTLEMENTS s
         WHERE s.status != 'ACCEPTED'
      GROUP BY s.auth_id) us ON us.auth_id = t.auth_id  
于 2009-08-10T17:36:31.973 に答える