1
votes

Trouver des écarts dans SQL (situation délicate)

J'ai du mal à essayer d'obtenir un résultat spécifique.

J'ai 2 tables, USERS et ADDRESSES.

Chaque client peut avoir plusieurs adresses liées à son numéro_compte particulier, jetez un œil:

Table USERS ( ID int, ACCOUNT_NUMBER int, ACCOUNT_NAME varchar (32) ):

'78983' | '14178' | '1st Street 478455' | '787' | 'SHIPPING_TO'
'78984' | '1419'  | '1st Street 0778'   | '788' | 'SHIPPING_TO'

Table ADDRESSES ( ADDRESS_ID int, ACCOUNT_NUMBER int, ADDRESS_NAME varchar (32), ADDRESS_ORG_ID int, ADDRESS_TYPE varchar (32) )

'78979' | '1417'  | '1st Street 4785'   | '787'   | 'SHIPPING_TO'
'78980' | '1417'  | '1st Street 4785'   | '788'   | 'SHIPPING_TO'
'78981' | '1418'  | '1st Street 0012'   | '787'   | 'SHIPPING_TO'
'78982' | '1418'  | '1st Street 0012'   | '788'   | 'SHIPPING_TO'
'78983' | '14178' | '1st Street 478455' | '787'   | 'SHIPPING_TO'
'78984' | '1419'  | '1st Street 0778'   | '788'   | 'SHIPPING_TO'
'78985' | '1420'  | '1st Street 78'     | '787'   | 'SHIPPING_TO'
'78986' | '1420'  | '1st Street 78'     | '788'   | 'SHIPPING_TO'

Je peux avoir deux ADDRESS_ORG_ID différents: 787 et 788

Chaque UTILISATEUR doit avoir le même nombre d'adresses de LIVRAISON pour chaque ADDRESS_ORG_ID.

Voici mon SQLFIDDLE

Je voudrais obtenir ces UTILISATEURS qui n'ont pas le même numéro; Je veux dire, cette sortie:

'1' | '1417'  | 'SUPERMARKET_1'
'2' | '1418'  | 'SUPERMARKET_2'
'3' | '14178' | 'SUPERMARKET_3'
'4' | '1419'  | 'SUPERMARKET_4'
'5' | '1420'  | 'SUPERMARKET_5'

Cela signifie que si un client a deux adresses de livraison liées au ADDRESS_ORG_ID = 787 , il DOIT AVOIR le même numéro pour un autre ADDRESS_ORG_ID = 788

J'ai essayé mais je n'ai pas obtenu un bon résultat, puis-je m'aider?

Remarque: J'utilise une base de données Oracle


0 commentaires

3 Réponses :


1
votes

Je souhaite obtenir les UTILISATEURS qui n'ont pas la même quantité

Si vous ne vous souciez que de ces deux organisations, vous pouvez utiliser:

select id, 
       sum(case when address_org_id = 787 then 1 else 0 end) as cnt_787,
       sum(case when address_org_id = 788 then 1 else 0 end) as cnt_788
from ADDRESSES a INNER JOIN
     USERS u
     ON a.account_number = u.account_number
group by id
having sum(case when address_org_id = 787 then 1 else 0 end) <>
       sum(case when address_org_id = 788 then 1 else 0 end) ;

Voici un violon db .

Ceci est basé sur votre question qui concerne les utilisateurs . Vous fournissez des résultats qui semblent être au niveau de l'adresse. Vous pouvez rejoindre la table d'adresses pour ce type d'informations - ou utiliser listagg () et d'autres fonctions d'agrégation.


1 commentaires

Hey Gordon, merci beaucoup d'avoir répondu! Je vérifie.



0
votes

La requête ci-dessous doit vous aider,

select * from addresses ad
where ad.account_number in (select a.account_number
from ADDRESSES a
group by a.account_number
having sum(DECODE(address_org_id, 787, 1,0)) <>
       sum(DECODE(address_org_id, 788, 1,0)));

Cheers !!

PS - Même la sous-requête vous permet d'atteindre le filtre souhaité. Cependant, la super-requête vous aiderait à obtenir la sortie souhaitée.


0 commentaires

0
votes

Vous pouvez utiliser la fonction analytique pour obtenir toutes les données (toutes les colonnes) de la table ADDRESSES qui n'ont pas le même nombre d'adresses.

SELECT ADDRESS_ID,ACCOUNT_NUMBER,ADDRESS_NAME,ADDRESS_ORG_ID, ADDRESS_TYPE
FROM
(select a.*, 
        COALESCE(SUM(CASE WHEN ADDRESS_ORG_ID = 787 THEN 1 END) 
                 OVER (PARTITION BY ACCOUNT_NUMBER),0) AS CNT787,
        COALESCE(SUM(CASE WHEN ADDRESS_ORG_ID = 788 THEN 1 END) 
                 OVER (PARTITION BY ACCOUNT_NUMBER),0) AS CNT788
   from ADDRESSES a)
WHERE CNT787 <> CNT788

SQL Fiddle


0 commentaires