如何使用SQL组筛选具有最大日期值的行

New*_*ode 7 sql group-by having-clause

我有下表

CREATE TABLE Test
    (`Id` int, `value` varchar(20), `adate` varchar(20))
;

INSERT INTO Test
    (`Id`, `value`, `adate`)
VALUES
    (1, 100, '2014-01-01'),
    (1, 200, '2014-01-02'),
    (1, 300, '2014-01-03'),
    (2, 200, '2014-01-01'),
    (2, 400, '2014-01-02'),
    (2, 30 , '2014-01-04'),
    (3, 800, '2014-01-01'),
    (3, 300, '2014-01-02'),
    (3, 60 , '2014-01-04')
;
Run Code Online (Sandbox Code Playgroud)

我想实现只选择具有最大日期值的Id的结果.即

Id,价值,adate

 1, 300,'2014-01-03'     
 2, 30 ,'2014-01-04'     
 3, 60 ,'2014-01-04'
Run Code Online (Sandbox Code Playgroud)

我怎样才能实现这个目的group by?我做了如下但不起作用.

Select Id,value,adate
from Test
group by Id,value,adate
having adate = MAX(adate)
Run Code Online (Sandbox Code Playgroud)

有人可以帮助查询吗?

Mik*_*ll' 11

选择每个ID的最大日期.

select id, max(adate) max_date
from test
group by id
Run Code Online (Sandbox Code Playgroud)

加入其中以获得其余列.

select t1.*
from test t1
inner join (select id, max(adate) max_date
            from test
            group by id) t2
on t1.id = t2.id and t1.adate = t2.max_date;
Run Code Online (Sandbox Code Playgroud)


Tec*_*hDo 5

Please try:

select 
  * 
from 
  tbl a
where 
  a.adate=(select MAX(adate) from tbl b where b.Id=a.Id)
Run Code Online (Sandbox Code Playgroud)

  • 我想知道为什么这不被认为是最好的解决方案。 (2认同)

Gar*_*thD 5

If you are using a DBMS that has analytical functions you can use ROW_NUMBER:

SELECT  Id, Value, ADate
FROM    (   SELECT  ID,
                    Value,
                    ADate,
                    ROW_NUMBER() OVER(PARTITION BY ID ORDER BY Adate DESC) AS RowNum
            FROM    Test
        ) AS T
WHERE   RowNum = 1;
Run Code Online (Sandbox Code Playgroud)

Otherwise you will need to use a join to the aggregated max date by Id to filter the results from Test to only those where the date matches the maximum date for that Id

SELECT  Test.Id, Test.Value, Test.ADate
FROM    Test
        INNER JOIN
        (   SELECT  ID, MAX(ADate) AS ADate
            FROM    Test
            GROUP BY ID
        ) AS MaxT
            ON MaxT.ID = Test.ID
            AND MaxT.ADate = Test.ADate;
Run Code Online (Sandbox Code Playgroud)