下面的查询是一个草稿,其中包含我要编写的查询中的相关列,因此不要将其视为解决方案。将其用作表和列名称的指南。我正在尝试删除相同的ORDER_ID和ACCOUNT_ID相互抵消的任何事务。我不认为我可以使用SUM进行聚合,因为这会将所有TX_AMOUNT值加在一起进行分组。请参见TX_ID 6和7.这些都需要在结果集中显示。如何输出下表中的TX_ID,并滤除任何不说“显示”的东西?
SELECT
T1.ACCOUNT_ID
T1.ORDER_ID,
T1.TX_ID
FROM TRANSACTION AS T1
WHERE
T1.ACCOUNT_ID IN (
SELECT T2.ACCOUNT_ID
FROM TRANSACTION AS T2
GROUP BY T2.ACCOUNT_ID, T2.ORDER_ID
HAVING SUM(T2.TX_AMOUNT) != 0 AND T2.ORDER_ID IS NOT NULL
)
AND T1.ORDER_ID IN (
SELECT T3.ORDER_ID
FROM TRANSACTION AS T3
GROUP BY T3.ACCOUNT_ID, T3.ORDER_ID
HAVING SUM(T3.TX_AMOUNT) != 0 AND T3.ORDER_ID IS NOT NULL
)
TX_ID ORDER_ID ACCOUNT_ID TX_AMOUNT
------------------------------------
1 A1 200 -3.00 <--------- DON'T SHOW THIS; OFFSET BY #2
2 A1 200 3.00 <--------- DON'T SHOW THIS; OFFSET BY #1
3 A1 200 3.00 <--------- SHOW THIS
4 A2 999 -10.01 <--------- DON'T SHOW THIS; OFFSET BY #5
5 A2 999 10.01 <--------- DON'T SHOW THIS; OFFSET BY #4
6 A2 999 10.01 <--------- SHOW THIS
7 A2 999 5.02 <--------- SHOW THIS
答案 0 :(得分:2)
版本2: MUCH 更清洁...... Working DEMO with comments(您可能需要点击运行它!)才能看到所需的结果(或者我有一个缓存问题)
tx_ID asc
而不是tx_Amount desc
排序(除了我需要在row_nubmer上订单之外没有任何其他目的),那么我们就会在FIFO方法之后首先一致地摆脱最低数量的匹配)
With CTE (TX_ID, ORDER_ID, ACCOUNT_ID, TX_AMOUNT) as (
SELECT 1, 'A1', 200, -3.00 UNION ALL
SELECT 2, 'A1', 200, 3.00 UNION ALL
SELECT 3, 'A1', 200, 3.00 UNION ALL
SELECT 4, 'A2', 999, -10.01 UNION ALL
SELECT 5, 'A2', 999, 10.01 UNION ALL
SELECT 6, 'A2', 999, 10.01 UNION ALL
SELECT 7, 'A2', 999, 5.02 ),
cte2 as (
SELECT A.*, row_number() over (partition by order_ID, Account_ID, Tx_Amount order by tx_Amount desc) RN
FROM cte A)
SELECT *
FROM cte2 A
WHERE NOT exists (SELECT *
FROM cte2 B
WHERE A.Order_ID = B.Order_ID
and A.Account_ID = B.Account_Id
and A.tx_Amount*-1 = B.tx_Amount
and A.RN = B.RN)
给我们:(注意我们应该通过将*更改为所需的字段来消除RN,但此时我太懒了)
+----+-------+----------+------------+-----------+----+
| | TX_ID | ORDER_ID | ACCOUNT_ID | TX_AMOUNT | RN |
+----+-------+----------+------------+-----------+----+
| 1 | 2 | A1 | 200 | 3,00 | 2 |
| 2 | 7 | A2 | 999 | 5,02 | 1 |
| 3 | 5 | A2 | 999 | 10,01 | 2 |
+----+-------+----------+------------+-----------+----+
版本1 :(抓住这个丑陋的;我的意思是认真的;谁这么想?)我这样做......
With CTE (TX_ID, ORDER_ID, ACCOUNT_ID, TX_AMOUNT) as (
SELECT 1, 'A1', 200, -3.00 UNION ALL
SELECT 2, 'A1', 200, 3.00 UNION ALL
SELECT 3, 'A1', 200, 3.00 UNION ALL
SELECT 4, 'A2', 999, -10.01 UNION ALL
SELECT 5, 'A2', 999, 10.01 UNION ALL
SELECT 6, 'A2', 999, 10.01 UNION ALL
SELECT 7, 'A2', 999, 5.02 ),
cte2 as (
SELECT *
FROM (Select A.Tx_Id aTx_ID
, A.order_ID as AOrderID
, A.Account_ID as AAccount_ID
, A.tx_Amount as ATx_Amount
, Row_number() over (partition by Order_ID, Account_ID, tx_Amount order by tx_Amount asc) ARN
from cte a
WHERE tx_Amount <=0) A
FULL OUTER JOIN (SELECT b.tx_Id
, b.order_Id
, b.Account_Id
, b.tx_Amount
, Row_number() over (partition by Order_ID, Account_ID, tx_Amount order by tx_Amount desc) BRN
FROM CTE B
WHERE tx_Amount>0) B
on A.AOrderID = B.Order_ID
and A.AAccount_ID = B.Account_ID
and A.ATx_Amount*-1 = B.tx_Amount
and A.ARN=B.BRN
Where a.Atx_ID is null
or B.tx_ID is null)
Select ATX_ID, AORDERID, AAccount_ID, ATX_AMOUNT from cte2 where ATX_ID is not null
UNION ALL
Select TX_ID, ORDER_ID, Account_ID, TX_AMOUNT from cte2 where TX_ID is not null