2017-08-29 1 views
1

Il a été marqué en tant que doublon et semble être expliqué un peu dans les questions liées, mais j'essaie toujours d'obtenir les colonnes DEBIT et CREDIT sur la même rangée.Oracle SQL: Obtenir l'enregistrement max pour chaque ID dupliqué dans la table de jointure automatique

J'ai créé une vue et je suis actuellement en train de me joindre à elle. J'essaye d'obtenir le Header_ID maximum pour chaque date.

My SQL est actuellement:

SELECT DISTINCT 
TAB1.id, 
TAB1.glperiods_id, 
MAX(TAB2.HEADER_ID), 
TAB1.batch_date, 
TAB1.debit, 
TAB2.credit, 
TAB1.descrip 

FROM 
IQMS.V_TEST_GLBATCH_GJ TAB1 

LEFT OUTER JOIN 
IQMS.V_TEST_GLBATCH_GJ TAB2 
ON 
TAB1.ID = TAB2.ID AND TAB1.BATCH_DATE = TAB2.BATCH_DATE AND TAB1.GLPERIODS_ID = TAB2.GLPERIODS_ID AND TAB1.DESCRIP = TAB2.DESCRIP AND TAB1.DEBIT <> TAB2.CREDIT 

WHERE 
TAB1.ACCT = '3648-00-0' 
AND 
TAB1.DESCRIP NOT LIKE '%INV%' 
AND TAB1.DEBIT IS NOT NULL 

GROUP BY 
TAB1.id, 
TAB1.glperiods_id, 
TAB1.batch_date, 
TAB1.debit, 
TAB2.credit, 
TAB1.descrip 

ORDER BY TAB1.batch_date 

Et la sortie en est (37 lignes au total):

Some rows

Je rejoins la table sur elle-même pour obtenir DEBIT et CREDIT sur la même ligne. Comment puis-je sélectionner uniquement les lignes avec le maximum HEADER_ID par BATCH_DATE?

Mise à jour

Pour @sagi

Ceux mis en évidence avec la boîte rouge sont les lignes que je veux et ceux en bleu seraient ceux que je filtrage sur.

enter image description here

erreur fixe

J'ai récemment remarqué que j'avais rejoint ma table sur elle-même sans que TAB2 ACCT = '3648-00-0.

Le SQL corrigée est ici:

SELECT DISTINCT 
TAB1.id, 
TAB1.glperiods_id, 
Tab1.HEADER_ID, 
TAB1.batch_date, 
TAB1.debit, 
TAB2.credit, 
TAB1.descrip 

FROM 
IQMS.V_TEST_GLBATCH_GJ TAB1 

LEFT OUTER JOIN 
IQMS.V_TEST_GLBATCH_GJ TAB2 
ON 
TAB1.ID = TAB2.ID AND TAB1.BATCH_DATE = TAB2.BATCH_DATE AND TAB2.ACCT ='3648-00-0'AND TAB1.GLPERIODS_ID = TAB2.GLPERIODS_ID AND TAB1.DESCRIP = TAB2.DESCRIP AND TAB1.DEBIT <> TAB2.CREDIT 

WHERE 
TAB1.ACCT = '3648-00-0' 
AND 
TAB1.DESCRIP NOT LIKE '%INV%' 
AND TAB1.DEBIT IS NOT NULL 

ORDER BY TAB1.BATCH_DATE 

Répondre

1

Utilisez la fonction de fenêtre comme ROW_NUMBER():

SELECT s.* FROM (
    SELECT t.*, 
      ROW_NUMBER() OVER(PARTITION BY t.batch_id ORDER BY t.header_id DESC) as rnk 
    FROM YourTable t 
    WHERE t.ACCT = '3648-00-0' 
     AND t.DESCRIP NOT LIKE '%INV%' 
     AND t.DEBIT IS NOT NULL) s 
WHERE s.rnk = 1 

Ceci est une fonction analytique qui se classent votre dossier par les valeurs indiquées dans la clause OVER.

PARTITION - is the group 
ORDER BY - Who's the first of this group (first gets 1, second 2, ETC) 

Il est beaucoup plus efficace rejoint alors (Votre problème aurait pu être résolu à bien des égards), et utilise la table qu'une seule fois.

+0

Merci pour votre réponse! Je vais essayer maintenant. N'a pas utilisé PARTITION PAR avant – spyr0

+0

Merci! Je pense que ça marche! Confus pour un moment parce que je n'ai pas vu le batch_id. Changé à batch_date – spyr0

+0

Non, attendez désolé. Il semble également se débarrasser du crédit sélectionné. – spyr0