2017-08-08 2 views
1

j'ai données comme ceci:ROW_NUMBER() sur deux colonnes, si, 2 lignes sont les mêmes alors

item_no p_no date  RN() 
35917 1220540 2000-04-03 1 
35917 1220540 2000-04-18 1 
35917 1220540 2001-02-12 1 
35917 1220540 2001-03-08 1 
35917 1220540 2001-03-19 1 
542672 1243288 2000-01-24 1 
564575 1243288 2000-01-24 2 
549816 1243288 2000-01-24 3 
542672 1243288 2000-02-25 1 
564575 1243288 2000-02-25 2 
549816 1243288 2000-02-25 3 

Je veux sélectionner un enregistrement pour chaque p_no, avec la date maximum (le plus récent record) . S'il y a 2 lignes avec le même p_no et la même date, je dois vérifier item_no et sélectionner record avec le plus haut. Exemple:

  • p_no = 1243288 a deux 2000-02-25 et 2000-01-24 DATES
  • Date 2000-02-25 est GREATEST si les enregistrements avec date = 2000-02-25 est ce Je suis à la recherche
  • il y a 3 enregistrements avec un même groupe (p_np, date) donc je dois sélectionner ENREGISTRE avec le plus grand No_article
  • dossier Je suis intéressé par:

    564575 1243288 2000-02-25 2

I utilisé ROW_NUMBER() pour obtenir la colonne RN

row_number() over (partition by p_no, date order by date desc) rnk, 

mais je ne sais pas comment utiliser cette colonne et vérifiez No_article pour sélectionner ce que je dois. Est-ce que mon approche est fausse? Des suggestions?

+0

Ajoutez simplement 'ITEM_NO desc' à la clause' order by' de la fonction analytique. Incidemment, si vous utilisez 12c [consultez cette réponse] (https://stackoverflow.com/a/43028479/146325) – APC

Répondre

0

Ajoutez item_no à la partie ORDER BY de la fonction de numéro de ligne afin qu'elle devienne ORDER BY date desc, item_no desc). L'idée est qu'il casse un lien entre mêmes éléments de la partition en disant quel élément doit venir d'abord si la date est la même

Pour utiliser votre RNK: Enveloppez votre toute instruction select dans un autre

SELECT * FROM (<your select statement>) WHERE rnk = 1 

exemple

SELECT * FROM (

    select employee.*, row_number() over(partition by department order by salary desc) as rnk 

) WHERE rnk = 1 --get highest paid in each dept 
0

Considérons cet exemple:

1 nous reproduisons votre table

CREATE TABLE #tmp (
item_no int 
,p_no int 
,[date] datetime 
) 

2 remplissiez avec les mêmes données que vous

INSERT INTO #tmp (item_no,p_no,[date]) VALUES (35917,1220540,'2000-04-03') 
INSERT INTO #tmp (item_no,p_no,[date]) VALUES (35917,1220540,'2000-04-18') 
INSERT INTO #tmp (item_no,p_no,[date]) VALUES (35917,1220540,'2001-02-12') 
INSERT INTO #tmp (item_no,p_no,[date]) VALUES (35917,1220540,'2001-03-08') 
INSERT INTO #tmp (item_no,p_no,[date]) VALUES (35917,1220540,'2001-03-19') 
INSERT INTO #tmp (item_no,p_no,[date]) VALUES (542672,1243288,'2000-01-24') 
INSERT INTO #tmp (item_no,p_no,[date]) VALUES (564575,1243288,'2000-01-24') 
INSERT INTO #tmp (item_no,p_no,[date]) VALUES (549816,1243288,'2000-01-24') 
INSERT INTO #tmp (item_no,p_no,[date]) VALUES (542672,1243288,'2000-02-25') 
INSERT INTO #tmp (item_no,p_no,[date]) VALUES (564575,1243288,'2000-02-25') 
INSERT INTO #tmp (item_no,p_no,[date]) VALUES (549816,1243288,'2000-02-25') 

3 Créer notre instruction select

SELECT * FROM (
SELECT 
    T.item_no 
    ,T.p_no 
    ,max(T.[date]) AS [max_date] 
    ,row_number() OVER (PARTITION BY T.p_no ORDER BY T.item_no desc) AS rn 
FROM 
    #tmp AS T 
GROUP BY 
    T.item_no 
    ,T.p_no 
) AS A 
WHERE 
    rn = 1 

Tout d'abord, nous trouvons la date maximale. Ensuite, nous partitionnons l'ensemble par p_no dans l'ordre de la plus haute No_article et donner les lignes de la valeur 1. Ensuite, nous choisissons tout avec un row_number = 1.

EDIT: Shorter/solution de rechange:

SELECT * FROM (
SELECT 
    T.item_no 
    ,T.p_no 
    ,T.[date] 
    ,row_number() OVER (PARTITION BY T.p_no ORDER BY T.[date] desc, T.item_no desc) AS rn 
FROM 
    #tmp AS T 
) AS A 
WHERE 
    rn = 1 
+0

cela semble une manière très compliquée d'atteindre l'objectif; Qu'offre-t-il par rapport à l'ajout de l'item no à la clause d'ordre de fonction analytique? –

+0

De nombreuses façons d'atteindre le même objectif. – ssn