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!

Si rownumber() over(...) está disponible para usted ….

 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 

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

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

 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, puede unirlas en OrderNo y MaxDate .

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 

Y también puede usar esa statement 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 🙂

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 

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); 

Trate de evitar EN USO ÚNASE

 SELECT SQL_CALC_FOUND_ROWS * FROM (SELECT msisdn, callid, Change_color, play_file_name, date_played FROM insert_log WHERE play_file_name NOT IN('Prompt1','Conclusion_Prompt_1','silent') ORDER BY callid ASC) t1 JOIN (SELECT MAX(date_played) AS date_played FROM insert_log GROUP BY callid) t2 ON t1.date_played=t2.date_played