Pregunta SQL Server: SELECCIONE solo las filas con MAX (DATE)


Tengo una tabla de datos (el db es 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

Me gustaría realizar una consulta que devuelva OrderNO, PartCode y Quantity, pero solo para la última orden registrada.

De la tabla de ejemplos me gustaría obtener la siguiente información:

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

Tenga en cuenta que solo se devolvió una línea para el pedido 9999.

¡Gracias!


74
2017-08-19 07:15


origen


Respuestas:


Si rownumber() over(...) está disponible para ti ....

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      

122
2017-08-19 07:22



La mejor manera es Mikael Eriksson, si ROW_NUMBER() está disponible para ti.

El siguiente mejor es unirse a una consulta, según la respuesta de Cularis.

Alternativamente, la forma más simple y directa es una subconsulta correlacionada en la cláusula WHERE.

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

O...

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

41
2017-08-19 07:27



select OrderNo,PartCode,Quantity
from dbo.Test t1
WHERE EXISTS(SELECT 1
         FROM dbo.Test t2
         WHERE t2.OrderNo = t1.OrderNo
           AND t2.PartCode = t1.PartCode
         GROUP BY t2.OrderNo,
                  t2.PartCode
         HAVING t1.DateEntered = MAX(t2.DateEntered))

Esta es la más rápida de todas las consultas proporcionadas anteriormente. El costo de la consulta llegó a 0.0070668.

La respuesta preferida anterior, por Mikael Eriksson, tiene un costo de consulta de 0.0146625

Es posible que no le importe el rendimiento de una muestra tan pequeña, pero en grandes consultas, todo se suma.


20
2017-11-04 03:39



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 consulta interna selecciona todo OrderNo con su fecha máxima. Para obtener las otras columnas de la tabla, puedes unirte a ellas en OrderNo y el MaxDate.


8
2017-08-19 07:19



Para MySql puede hacer algo como lo siguiente:

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

1
2017-08-19 07:23



Y también puede usar esa declaración de selección como consulta de combinación izquierda ... Ejemplo:

... 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 ....

Espero que esto ayude a alguien que busque esto :)


1
2017-10-07 05:01



rownumber () sobre (...) funciona, pero no me gustó esta solución por dos razones.  - Esta función no está disponible cuando usa una versión anterior de SQL como SQL2000  - Dependencia de la función y no es realmente legible.

Otra solución es:

SELECT tmpall.[OrderNO] ,
       tmpall.[PartCode] ,
       tmpall.[Quantity] ,
FROM   (SELECT [OrderNO],
               [PartCode],
               [Quantity],
               [DateEntered]
        FROM   you_table) AS tmpall
       INNER JOIN (SELECT [OrderNO],
                          Max([DateEntered]) AS _max_date
                   FROM   your_table
                   GROUP  BY OrderNO ) AS tmplast
               ON tmpall.[OrderNO] = tmplast.[OrderNO]
                  AND tmpall.[DateEntered] = tmplast._max_date

1
2017-07-28 21:34



Si tiene ID indexado y OrderNo, puede usar IN: (Odio la simplicidad de trading por oscuridad, solo para guardar algunos ciclos):

select * from myTab where ID in(select max(ID) from myTab group by OrderNo);

1
2018-01-04 13:29