5

トランザクションを含むテーブルがあります。各トランザクションには、トランザクション ID、会計期間 (AP)、転記値 (PV)、およびその他のフィールドがあります。通常、トランザクションが誤って実行されたため、一部の ID が重複しています。例を挙げると、テーブルの一部は次のようになります。

ID    PV    AP  
123   100   2  
123   -100  5  

この場合、トランザクションは AP2 で追加され、AP5 で削除されました。

別の例は次のとおりです。

ID    PV    AP  
456   100   2  
456   -100  5  
456   100   8

最初の例の問題は、AP2 で費やされたものを分析している場合、AP5 で再び取り出されたため、実際には考慮すべきではないトランザクションがそこにあるということです。2 番目の例では、2 番目の 2 つのトランザクションは互いに相殺されるため、考慮に入れるべきではありません。

エラーとして考慮されるべきではない、できるだけ多くのトランザクションにラベルを付けたいと思います。これらのトランザクションを識別するには、2 番目の例のように、PV の合計がゼロになる重複 ID を持つトランザクション (上記の ID 123 など)、または最初のトランザクションの PV が sum(PV) に等しいトランザクションを見つけたいと考えています。この 2 番目の状態が、私を悲しませている原因です。

これまでのところ、

SELECT *
FROM table
WHERE table.ID IN (SELECT table.ID
                    FROM table
                    GROUP BY table.ID
                    HAVING COUNT(*) > 1
                    AND (SUM(table.PV) = 0
                    OR SUM(table.PV) = <PV of first transaction in each group>))
ORDER BY table.ID;

シェブロンのビットは、私がやろうとしていることであり、立ち往生しています。このようにすることはできますか、または SQL でこれを行うために使用できる他の方法はありますか?

編集 1: ところで、重要な場合に備えて、SQL Compact 3.5 を使用していることを忘れていました。

編集 2: 上記のコード スニペットは少し誤解を招くと思います。最初の例のように、sum(PV) = 0 の重複 ID を持つトランザクションをマークアウトしたいと考えています。しかし、最初のトランザクションの PV = sum(PV) の場合、2 番目の例のように、私が実際に望んでいるのは、最初のトランザクションを保持し、他のすべてのトランザクションを同じ ID でマークすることです。混乱を招いた場合は申し訳ありません。

編集 3: 私は Clodoaldo のソリューションで遊んでいて、ある程度の進歩を遂げましたが、まだ私が望むものを得ることができません. 私は、間違いであると確信しているトランザクションを取得しようとしています。次のトランザクションもテーブルにあるとします。

ID     PV    AP  
789    100   2  
789    200   5  
789   -100   8

この例では、sum(PV) <> 0 で、最も古い PV <> sum(PV) であるため、これらのいずれにもマークを付けたくありません。

Clodoaldo のクエリを次のように変更すると、次のようになります。

    select t.*
    from 
    t
    left join (
        select id, min(ap) as ap, sum(pv) as sum_pv
        from t
        group by id
        having sum(pv) <> 0
    ) s on t.id = s.id and t.ap = s.ap and t.pv = s.sum_pv
     where s.id is null

これにより結果が得られます

 ID      PV     AP
123      100    2
123     -100    5
456     -100    5
456      100    8
789      100    3
789      200    5
789     -100    8

最初の 4 つのトランザクションは問題ありませんが (それらはマーク アウトされます)、789 のトランザクションもそこにあり、それらは必要ありません。しかし、それらが含まれないようにクエリを変更する方法がわかりません。何か案は?

4

2 に答える 2

2

SQL フィドル

select t.* 
from 
    t
    inner join (
        select id, min(ap) as ap
        from t
        group by id
        having sum(pv) <> 0
    ) s on t.id = s.id and t.ap = s.ap

上記は有効なトランザクションを取得します。無効なものが必要な場合は、これを使用します。

select t.*
from 
    t
    left join (
        select id, min(ap) as ap
        from t
        group by id
        having sum(pv) <> 0
    ) s on t.id = s.id and t.ap = s.ap
where s.id is null

SQL フィドル

于 2012-10-09T15:49:00.127 に答える
0

次のようなものを試してください。

UPDATE
    Transactions
SET
    IsError = true
WHERE
    EXISTS
    (SELECT
        NULL
    FROM 
        Transactions SubsequentTransactions
    WHERE
        Transactions.ID = SubsequentTransactions.ID
    AND Transactions.AP < SubsequentTransactions.AP
    AND Transactions.PV = -1 * SubsequentTransactions.PV)

私はそれがうまくいくと思います。私はそれをまったくテストしていないので、最初にselectステートメントでWHERE句を使用して、必要な行にのみ影響することを確認することをお勧めします。

これは、2番目の例を除いて、ネガティブトランザクションをエラーとしてフラグ付けしません(必要な場合とそうでない場合があります)。2番目の例では、3番目のレコードがあり、それらが分離されている場合、2番目のレコードをキャンセルします。必要なものを完全に取得するには、ロジックを拡張する必要があるかもしれませんが、それで開始できるはずです。

于 2012-10-09T15:43:34.417 に答える