La requête ci-dessous est un brouillon contenant les colonnes pertinentes dans la requête que je voudrais écrire, alors ne le regardez pas comme une solution. Utilisez-le comme un guide pour les noms de table et de colonne. J'essaie de supprimer toutes les transactions qui se compensent pour les mêmes ORDER_ID et ACCOUNT_ID. Je ne pense pas que je puisse faire un agrégat en utilisant SUM, car cela appendait toutes les valeurs TX_AMOUNT pour le regroupement. Voir TX_ID 6 et 7. Ces deux doivent apparaître dans le jeu de résultats. Comment puis-je sortir le TX_ID de la table ci-dessous, et filterr tout ce qui ne dit pas "SHOW THIS"?
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
VERSION 2: BEAUCOUP plus propre … DEMO de travail avec des commentaires (vous devrez peut-être cliquer sur Exécuter!) Pour voir les résultats souhaités (ou peut-être que j'ai un problème de caching)
tx_ID asc
au lieu de tx_Amount desc
(ce qui ne sert vraiment à rien d'autre que j'ai besoin d'un ordre sur le row_nubmer), alors nous nous débarrasserons du nombre le plus bas suivant l'approche 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)
En nous donnant: (notez que nous devrions éliminer le RN en changeant * aux champs désirés mais je suis trop paresseux à ce point)
+----+-------+----------+------------+-----------+----+ | | 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 | +----+-------+----------+------------+-----------+----+
VERSION 1: (Scratch ce laid, je veux dire sérieusement, qui pense comme ça?) Je fais …
DEMO
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