2008-11-19 13 views
4

J'ai un tableau des transactions qui auront occasionnellement entrées en double. Si/Quand un administrateur trouve ces entrées en double, il inversera les transactions, créant ainsi une valeur négative (mais le duplicata original reste dû aux exigences réglementaires). Je souhaite créer une requête SQL (et utiliser Crystal Reports) pour créer un rapport permettant aux administrateurs de trouver facilement les transactions en double. En raison de la quantité massive de transactions, je voudrais leur faciliter la tâche en ne tenant pas compte des transactions qu'elles ont déjà annulées.SQL - Besoin de trouver des enregistrements en double, mais EXCLUDE transactions inversées

Voici un exemple de ce que je voudrais faire:

Date de la transaction; Quantité de transaction; Valeur de transaction; Inversion

1/1/08 ; 14 ; 70.00 ; N 
1/1/08 ; 14 ; 70.00 ; N 
1/1/08 ; -14 ; -70.00 ; Y 
2/1/08 ; 17 ; 89.00 ; N 
2/15/08 ; 18 ; 95.00 ; N 
2/15/08 ; 18 ; 95.00 ; N 
3/1/08 ; 11 ; 54.00 ; N 
3/1/08 ; -11 ; -54.00 ; Y 
3/1/08 ; 11 ; 54.00 ; N 
3/1/08 ; 11 ; 54.00 ; N 
3/1/08 ; 11 ; 54.00 ; N 

Idéalement, si je courais ma requête "désirée" sur le tableau ci-dessus, je recevoir le résultat suivant:

Date de la transaction; Quantité de transaction; Valeur de transaction; Nombre

2/15/08 ; 18 ; 95.00 ; 2 
3/1/08  ; 11 ; 54.00 ; 3 

Est-ce logique? J'ai déjà compris comment écrire la requête pour me donner le nombre de doublons, mais je ne peux pas comprendre comment pour exclure les enregistrements en double qui ont déjà été "sauvegardés". Toute aide serait grandement appréciée!

+0

Êtes-vous allez devoir gérer des inversions partielles aussi bien? –

Répondre

4

Que diriez-vous:

select dt, abs(qty), abs(val), 
     sum(case when reversal='Y' then -1 else 1 end) as count 
from transactions 
group by dt, abs(qty), abs(val) 
having sum(case when reversal='Y' then -1 else 1 end) > 1; 

Je viens de tester dans Oracle et il fonctionne:

create table transactions 
(dt date 
, qty number 
, val number 
, reversal varchar2(1) 
); 

insert into transactions values (to_date('1/1/08','mm/dd/yy') , 14 , 70.00 , 'N'); 
insert into transactions values (to_date('1/1/08','mm/dd/yy') , 14 , 70.00 , 'N'); 
insert into transactions values (to_date('1/1/08','mm/dd/yy') , -14 , -70.00 , 'Y'); 
insert into transactions values (to_date('2/1/08','mm/dd/yy') , 17 , 89.00 , 'N'); 
insert into transactions values (to_date('2/15/08','mm/dd/yy') , 18 , 95.00 , 'N'); 
insert into transactions values (to_date('2/15/08','mm/dd/yy') , 18 , 95.00 , 'N'); 
insert into transactions values (to_date('3/1/08','mm/dd/yy') , 11 , 54.00 , 'N'); 
insert into transactions values (to_date('3/1/08','mm/dd/yy') , -11 , -54.00 , 'Y'); 
insert into transactions values (to_date('3/1/08','mm/dd/yy') , 11 , 54.00 , 'N'); 
insert into transactions values (to_date('3/1/08','mm/dd/yy') , 11 , 54.00 , 'N'); 
insert into transactions values (to_date('3/1/08','mm/dd/yy') , 11 , 54.00 , 'N'); 

SQL> select dt, abs(qty), abs(val), 
    2   sum(case when reversal='Y' then -1 else 1 end) as count 
    3 from transactions 
    4 group by dt, abs(qty), abs(val) 
    5 having sum(case when reversal='Y' then -1 else 1 end) > 1; 

DT   ABS(QTY) ABS(VAL)  COUNT 
----------- ---------- ---------- ---------- 
15-FEB-2008   18   95   2 
01-MAR-2008   11   54   3 
+0

Merci pour votre commentaire sur mon message; Ma requête était loin et je l'ai enlevé. Bravo –

+0

Wow, c'est exactement ce dont j'avais besoin .... Cela fonctionne parfaitement! Merci beaucoup de m'avoir sauvé d'un mal de tête. Vous devez être assez bon pour arriver à cette solution si rapidement. Merci encore! – Leslie

+0

Ça a l'air bien. À moins qu'un renversement ait une erreur (n'a pas la quantité et la valeur correctes), devrait faire l'affaire. –