0

我有一个与这个问题密切相关的 sql 问题 - SQL - Need to find duplicate records but EXCLUDE reversed transactions

我需要使用(如果可能)非过程 SQL 删除记录集的所有反转“对”。具体的 rdbms 是 Oracle 11g,但我希望 SQL 尽可能通用,以便在 SQL Server 2008 中使用相同的策略。示例记录集如下所示:


 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           |

请注意,重复是可能的,但总是需要删除反转“对”。

编辑 行和行号无关紧要,仅用于说明。删除哪些记录并不重要,只是总有一个“对”——一个正数和负数。因此,例如,第 2 行可以与 1、3、4 或 5 配对并删除。

此外,填充表的逻辑和表结构本身由供应商软件控制,并且不包括在冲销记录中被冲销的记录的原始 ID。我真的无法控制这个。 /编辑

顺便说一句,如果 MINUS 关键字被更改,它的功能类似于 UNION 和 UNION ALL,我会很高兴 - 因为 MINUS 只会删除与第二个记录集匹配的单个行集,但 MINUS ALL 会删除与第二个记录集匹配的每一行记录集。如果是这样的话,这个问题将是微不足道的(至少对于我的大脑思考方式而言)。

4

2 回答 2

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

这应该适用于 SQL 和 Oracle,因为它们都支持 row_number 窗口/分析函数。

请注意,此解决方案不保证反转是正确的。它还假设逆转发生在原始交易的同一天。

于 2012-05-01T19:34:45.870 回答
0

事实证明,我正在以一种非常糟糕的方式看待这个问题。我没有找到确切的反转对,而是用 GROUP BY 做了一个 SUM,所以只保留了我关心的值。

最终结果是交易最终会变得不同——尤其是在我的情况下,真正的交易表实际上是一个日期时间值而不是日期。

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

The only time this won't produce the values that you really want are if you have a need to maintain the id's of the transactions, or if you have a situation in which multiple transactions occur at the exact same time.

于 2012-07-09T11:53:31.407 回答