0

この質問に密接に関連するSQLの質問があります-SQL-重複したレコードを見つける必要がありますが、EXCLUDEはトランザクションを逆にしました

(可能であれば) 非手続き型 SQL を使用して、レコードセットの反転 "ペア" をすべて削除する必要があります。特定の rdbms は Oracle 11g ですが、SQL Server 2008 で同じ戦略を使用できるように、SQL をできるだけ一般的なものにしたいと考えています。レコードセットの例は次のようになります。


 ROW     |    DATE    |    QTY    |    FUEL_TYPE    |    REVERSAL    |
1        | 01-MAY-12  |    23.3   |    DSL          |    N           |
2        | 01-MAY-12  |   -23.3   |    DSL          |    Y           |
3        | 01-MAY-12  |    23.3   |    DSL          |    N           |
4        | 01-MAY-12  |    23.3   |    DSL          |    N           |
5        | 01-MAY-12  |    23.3   |    DSL          |    N           |
6        | 01-MAY-12  |    18.6   |    DSL          |    N           |
7        | 01-MAY-12  |   -18.6   |    DSL          |    Y           |
8        | 01-MAY-12  |    14.9   |    GAS          |    N           |

クエリの望ましい結果は、このレコードセットを次のように減らします。


 ROW     |    DATE    |    QTY    |    FUEL_TYPE    |    REVERSAL    |
3        | 01-MAY-12  |    23.3   |    DSL          |    N           |
4        | 01-MAY-12  |    23.3   |    DSL          |    N           |
5        | 01-MAY-12  |    23.3   |    DSL          |    N           |
8        | 01-MAY-12  |    14.9   |    GAS          |    N           |

重複は可能ですが、反転「ペア」は常に削除する必要があることに注意してください。

edit 行と行番号は無関係であり、単に説明するために使用されています。どのレコードが削除されるかは問題ではなく、常に「ペア」、つまりプラスの金額とマイナスの金額が存在するということだけです。したがって、たとえば、行 2 を 1、3、4、または 5 とペアにして削除することができます。

また、テーブルとテーブル構造自体にデータを入力するロジックは、ベンダー ソフトウェアによって制御され、リバーサル レコードでリバースされるレコードの元の ID は含まれません。私は本当にこれを制御することはできません。 /編集

ちなみに、MINUS キーワードが UNION および UNION ALL と同様に機能するように変更された場合、MINUS は 2 番目のレコードセットから一致する単一の行セットのみを削除しますが、MINUS ALLは 2 番目の値に一致するすべての行を削除します。レコードセット。もしそうなら、この問題は些細なことです (少なくとも私の脳が考える方法では)。

4

2 に答える 2

0

私はかなりひどい方法で問題を見ていました。正確な反転ペアを見つける代わりに、GROUP BY を使用して SUM を実行しただけなので、保持する必要がある値だけが残りました。

最終結果として、トランザクションは個別のものになります。特に、私の場合のように、実際のトランザクション テーブルが実際には日付ではなく日時の値である場合はなおさらです。

SELECT SUM(QTY) AS newQTY, DATE, FUEL_TYPE
FROM fuel_transactions
GROUP BY DATE, FUEL_TYPE

これが本当に必要な値を生成しないのは、トランザクションの ID を維持する必要がある場合、または複数のトランザクションがまったく同時に発生する状況にある場合だけです。

于 2012-07-09T11:53:31.407 に答える
0

あなたが直面している問題は、取り消しが取り消されているトランザクションに直接割り当てられていないことです。

反転が正確な反転であると仮定すると、次のアプローチをとることができます。特定のトランザクション情報のセットについて、反転と非反転を列挙します。次に、一致しない非反転をすべて取得します。

これを行う SQL の例を次に示します。

with t as 
(
  select row, date, qty, fuel_type, reversal,
    ROW_NUMBER() over (partition by row, date, qty, fuel_type, reversal) as rownum
  from table
)
select *
from 
(
   select *
   from t
   where t.reversal = 'N'
 ) n 
 left outer join
 (
   select *
   from t
   where t.reversal = 'Y'
 ) y
    on n.date = y.date 
    and n.qty = y.qty 
    and n.fuel_type = y.fuel_type 
    and n.rownum = y.rownum 
where n.row is null

どちらもrow_numberウィンドウ/分析関数をサポートしているため、これはSQLとOracleの両方で機能するはずです。

このソリューションは、反転が正しいことを保証するものではないことに注意してください。また、元の取引と同じ日に反転が発生したと想定しています。

于 2012-05-01T19:34:45.870 に答える