SQLServer: 只选择具有 MAX (DATE)的行

我有一个数据表(db 是 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

我想做一个查询,返回 OrderNO,PartCode 和 Quantity,但只是为最后注册的订单。

我想从示例表中得到以下信息:

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

注意,订单9999只返回了一行。

谢谢!

479806 次浏览
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)

内部查询选择所有 OrderNo及其最大日期。要获得表的其他列,可以在 OrderNoMaxDate上将它们联接起来。

如果你有 rownumber() over(...)..。

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

对于 MySql,您可以执行以下操作:

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

最好的办法是迈克尔埃里克森,如果 ROW_NUMBER()是可用的。

接下来最好的方法是按照 Cularis 的回答加入查询。

或者,最简单直接的方法是 WHERE 子句中的关联子查询。

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

或者..。

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

您还可以使用这个 select 语句作为左连接查询..。 例如:

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

希望这对搜索这个的人有所帮助:)

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

这是上面提供的所有查询中最快的一个,查询成本为0.0070668。

上面由 Mikael Eriksson 提供的首选答案的查询开销为0.0146625

您可能不关心这样一个小样本的性能,但是在大型查询中,这些都是有意义的。

尽量避免在使用中连接

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

Rownumber () over (...)正在工作,但是我不喜欢这个解决方案有两个原因。 - 当您使用旧版本的 SQL (如 SQL2000)时,此函数不可用 - 依赖于函数,并且不是真正可读的。

另一个解决办法是:

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

如果您已经索引了 ID 和 OrderNo,您可以使用 IN: (我讨厌用简单性换取模糊性,只是为了节省一些周期) :

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

这对我有用。使用 MAX (CONVERT (date,ReportDate))来确保你有日期值

select max( CONVERT(date, ReportDate)) FROM [TraxHistory]

这招对我很管用。

    select name, orderno from (
select name, orderno, row_number() over(partition by
orderno order by created_date desc) as rn from orders
) O where rn =1;

为了补充 Mikael Eriksson 的答案,当你有带有相同日期的重复行(OrderNO,PartCode)时,你应该如何使用它有一个细微的差别。你可使用:

  1. Row _ number () 将只返回一行,删除重复行
  2. Rank () 将返回所有重复的行

原来我需要的是 军衔而不是 Row _ number

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