2014-07-01 3 views
0

Je n'arrive pas à filtrer les résultats d'une requête. Ici, il est la requête que je suis l'exécution:Filtrage des lignes dans la requête jointe

SELECT 
ORE.ID AS OR_ID, 
ORE.INIT_VERSION AS OR_INIT_VERSION, 
ORE.INSERT_DATE AS OR_INSERT_DATE, 
ORE.INIT_DATE AS OR_INIT_DATE, 
ORE.END_DATE AS OR_END_DATE, 
ORE.STATE AS OR_STATE, 
ORE.ACTION_NAME AS OR_ACTION_NAME, 
ORH.STATE_ID AS ORH_STATE_ID, 
ORH.INSERT_DATE AS ORH_INSERT_DATE, 
CS.STATE AS CS_STATE 

FROM ORDER_REQUEST ORE 
INNER JOIN ORDER_REQUEST_HISTORY ORH ON ORH.ORDER_REQUEST_ID = ORE.ID AND ORH.COMPONENT_ID = ORE.ARCH_ID 
INNER JOIN COMPONENT_STATE CS ON CS.ID = ORH.STATE_ID 
WHERE ORE.ARCH_ID = 219934 
AND CS.STATE IN ('CREAZIONE', 'ANNULLATO', 'REVISIONE PIANIFICATA', 'APPROVAZIONE PIANIFICATA', 'APPROVAZIONE RIFIUTATA', 'COMPLETATO', 'COMPLETATA') 

qui renvoie le résultat suivant:

OR_ID OR_STATE OR_INIT_DATE OR_ACTION_NAME ORH_STATE_ID OR_END_DATE  CS_STATE ORH_INSERT_DATE  OR_INSERT_DATE   OR_INIT_VERSION 
8821 COMPLETATA 2014-04-07  ATT    111    2014-06-03  COMPLETATA 15-05-2014 12:48:32 07-04-2014 16:49:42  1 
12266 ACQUISITO 2014-06-03  VAR    10018   NULL   CREAZIONE 30-06-2014 18:59:40 03-06-2014 15:53:51  2 
12266 ACQUISITO 2014-06-03  VAR    10018   NULL   CREAZIONE 01-07-2014 12:56:20 03-06-2014 15:53:51  2 

J'aimerais filtrer de telle sorte que pour chaque OR_ID je ne reçois que la ligne avec le maximum ORH_INSERT_DATE, c'est-à-dire la première et la troisième ligne du résultat. J'ai essayé différentes approches, mais aucune ne semble fonctionner. En particulier, j'ai essayé de compliquer la REJOIGNEZ:

INNER JOIN ORDER_REQUEST_HISTORY ORH ON ORH.ORDER_REQUEST_ID = ORE.ID AND ORH.COMPONENT_ID = ORE.ARCH_ID AND ORH.INSERT_DATE = (SELECT INSERT_DATE FROM ORDER_REQUEST_HISTORY ORH2 WHERE ORH2.ORDER_REQUEST_ID = ORE.ID) 

mais il retourne uniquement la première ligne des résultats ci-dessus. J'ai aussi essayé de compliquer la clause WHERE de la même manière, mais elle ne me renvoie que la première ligne du résultat ci-dessus.

Quelqu'un a-t-il une idée de la bonne clause à ajouter? Ou devrais-je passer pour faire des requêtes ultérieures et le résoudre de la bonne manière?

Merci beaucoup à l'avance,

Gianluca

Répondre

1

Vous pouvez utiliser WITH clause et ROW_NUMBER fonction de cela, comme ceci:

WITH CTE AS 
(
SELECT 
ORE.ID AS OR_ID, 
ORE.INIT_VERSION AS OR_INIT_VERSION, 
ORE.INSERT_DATE AS OR_INSERT_DATE, 
ORE.INIT_DATE AS OR_INIT_DATE, 
ORE.END_DATE AS OR_END_DATE, 
ORE.STATE AS OR_STATE, 
ORE.ACTION_NAME AS OR_ACTION_NAME, 
ORH.STATE_ID AS ORH_STATE_ID, 
ORH.INSERT_DATE AS ORH_INSERT_DATE, 
CS.STATE AS CS_STATE, 
ROW_NUMBER() OVER (PARTITION BY ORE.ID ORDER BY ORH.INSERT_DATE DESC) AS RN 
FROM ORDER_REQUEST ORE 
INNER JOIN ORDER_REQUEST_HISTORY ORH ON ORH.ORDER_REQUEST_ID = ORE.ID AND  ORH.COMPONENT_ID = ORE.ARCH_ID 
INNER JOIN COMPONENT_STATE CS ON CS.ID = ORH.STATE_ID 
WHERE ORE.ARCH_ID = 219934 
AND CS.STATE IN ('CREAZIONE', 'ANNULLATO', 'REVISIONE PIANIFICATA', 'APPROVAZIONE PIANIFICATA', 'APPROVAZIONE RIFIUTATA', 'COMPLETATO', 'COMPLETATA') 
) 

SELECT * 
FROM CTE 
WHERE RN = 1 

L'idée est de partition sur la base OR_ID et trouvez la ligne avec la valeur maximale pour ORH_INSERT_DATE. Vous pouvez également sélectionner uniquement des colonnes spécifiques en remplaçant les colonnes souhaitées par *.

+0

Vous êtes un f *** ing génious! – Gianluca

+0

En fait, je suis sûr qu'il y a une meilleure façon de le faire sans CTE, mais je suis loin de ma boîte de dev, donc je ne peux pas tester et poster ça. –

+1

Eh bien, j'ai en fait perdu une matinée entière à faire fonctionner cette requête en essayant beaucoup de choses: compliquer la jointure, compliquer l'endroit, utiliser des sous-sélections, etc. J'ai votre réponse qui fonctionne pour moi, ce qui est bien. Merci encore – Gianluca

Questions connexes