151 votes

SQL Server : SELECTIONNER uniquement les lignes avec MAX(DATE)

J'ai une table de données (la base de données est MSSQL) :

ID  OrderNO  PartCode  Quantity DateEntered
417 2144     44917     100      18-08-11
418 7235     11762     5        18-08-11
419 9999     60657     100      18-08-11
420 9999     60657     90       19-08-11

Je voudrais faire une requête qui renvoie le numéro de commande, le code pièce et la quantité, mais uniquement pour la dernière commande enregistrée.

À partir du tableau d'exemple, je voudrais obtenir les informations suivantes :

 OrderNO  PartCode  Quantity     
 2144     44917     100      
 7235     11762     5        
 9999     60657     90  

Remarquez qu'une seule ligne a été renvoyée pour la commande 9999.

Merci !

3 votes

D'après votre commentaire, allez-y avec la réponse ROW_NUMBER(). Elle peut sembler plus longue, mais elle est, d'après mon expérience, beaucoup plus rapide avec des index appropriés.

1 votes

Merci Dems, j'apprécie votre effort.

2 votes

@GEMI juste par curiosité, n'est pas MAX(DATE) renvoie une ligne pour la commande 9999 ?

238voto

Mikael Eriksson Points 77190

Si rownumber() over(...) est disponible pour vous ....

select OrderNO,
       PartCode,
       Quantity
from (select OrderNO,
             PartCode,
             Quantity,
             row_number() over(partition by OrderNO order by DateEntered desc) as rn
      from YourTable) as T
where rn = 1

3 votes

Merci Mikael Eriksson, c'est une requête géniale !

72voto

MatBailie Points 37610

La meilleure voie est Mikael Eriksson, si ROW_NUMBER() est à votre disposition.

La meilleure solution suivante est de faire une jointure sur une requête, comme dans la réponse de Cularis.

La méthode la plus simple et la plus directe consiste à utiliser une sous-requête corrélée dans la clause WHERE.

SELECT
  *
FROM
  yourTable AS [data]
WHERE
  DateEntered = (SELECT MAX(DateEntered) FROM yourTable WHERE orderNo = [data].orderNo)

Ou...

WHERE
  ID = (SELECT TOP 1 ID FROM yourTable WHERE orderNo = [data].orderNo ORDER BY DateEntered DESC)

14voto

Jacob Points 17521
SELECT t1.OrderNo, t1.PartCode, t1.Quantity
FROM table AS t1
INNER JOIN (SELECT OrderNo, MAX(DateEntered) AS MaxDate
            FROM table
            GROUP BY OrderNo) AS t2
ON (t1.OrderNo = t2.OrderNo AND t1.DateEntered = t2.MaxDate)

La requête interne sélectionne tous les OrderNo avec leur date maximale. Pour obtenir les autres colonnes de la table, vous pouvez les joindre sur OrderNo et le MaxDate .

3voto

idzi Points 1

Et vous pouvez également utiliser cette instruction de sélection comme requête de jointure à gauche... Exemple :

... left join (select OrderNO,
   PartCode,
   Quantity from (select OrderNO,
         PartCode,
         Quantity,
         row_number() over(partition by OrderNO order by DateEntered desc) as rn
  from YourTable) as T where rn = 1 ) RESULT on ....

J'espère que cela aidera quelqu'un qui cherche cela :)

1voto

bencobb Points 548

Pour MySql, vous pouvez faire quelque chose comme ce qui suit :

select OrderNO, PartCode, Quantity from table a
join (select ID, MAX(DateEntered) from table group by OrderNO) b on a.ID = b.ID

0 votes

Vous ne pouvez pas sélectionner l'ID dans la table interne si vous regroupez par numéro de commande.

0 votes

@Dems merci@cularis oui, cela fait référence à MySql, la question ne précisait pas quel moteur de base de données

1 votes

Si vous publiez des échantillons de code, de XML ou de données, s'il vous plaît mettez en évidence ces lignes dans l'éditeur de texte et cliquez sur le bouton "échantillons de code" ( { } ) dans la barre d'outils de l'éditeur pour le formater et le mettre en évidence !

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X