SQL Server:仅选择MAX行(DATE)

时间:2011-08-19 07:15:40

标签: sql-server

我有一个数据表(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只返回了一行。

谢谢!

11 个答案:

答案 0 :(得分:151)

如果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      

答案 1 :(得分:52)

最好的方法是Mikael Eriksson,如果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)

答案 2 :(得分:24)

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

您可能不关心这么小的样本的性能,但在大型查询中,这一切都会增加。

答案 3 :(得分:10)

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上加入。

答案 4 :(得分:2)

如果你有索引ID和OrderNo你可以使用IN :(我讨厌简单交易,只是为了节省一些周期):

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

答案 5 :(得分: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

答案 6 :(得分:1)

你也可以使用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 ....

希望这有助于搜索此内容的人:)

答案 7 :(得分:1)

rownumber()over(...)正在运行,但由于两个原因我不喜欢这个解决方案。   - 使用SQL2000等旧版本的SQL时,此功能不可用   - 对功能的依赖,并不是真正的可读性。

另一种解决方案是:

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

答案 8 :(得分:0)

尽量避免使用JOIN

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

答案 9 :(得分:0)

这对我来说很好。

    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;

答案 10 :(得分:-1)

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

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