我有一个表,它是一个关于用户何时登录的集合条目。

username, date,      value
--------------------------
brad,     1/2/2010,  1.1
fred,     1/3/2010,  1.0
bob,      8/4/2009,  1.5
brad,     2/2/2010,  1.2
fred,     12/2/2009, 1.3

etc..

我如何创建一个查询,将给我每个用户的最新日期?

更新:我忘记了我需要有一个值与最近的日期。


当前回答

SELECT *     
FROM MyTable T1    
WHERE date = (
   SELECT max(date)
   FROM MyTable T2
   WHERE T1.username=T2.username
)

其他回答

如果您的数据库语法支持它,那么TOP 1 WITH TIES可以与rownumber结合使用。

对于您提供的示例数据,使用以下查询:

SELECT TOP 1 WITH TIES
  username, date, value
FROM user_log_in_attempts
ORDER BY ROW_NUMBER() OVER (PARTITION BY username ORDER BY date DESC)

它的收益率:

username | date      | value
-----------------------------
bob      | 8/4/2009  | 1.5
brad     | 2/2/2010  | 1.2
fred     | 12/2/2009 | 1.3

Demo

工作原理:

Rownumber () over (partition by…ORDER BY…)对于每个用户名,计算从最年轻的(rownumber=1)到最老的(rownumber=high)的行列表。 按行号排序…将每个用户最年轻的行排序到最上面,然后是每个用户第二年轻的行,依此类推 因为每个用户都有一个最年轻的行,这些最年轻的行在排序条件的意义上是相等的(都有rownumber=1)。所有最年轻的行都将返回。

用SQL-Server测试。

SELECT DISTINCT Username, Dates,value 
FROM TableName
WHERE  Dates IN (SELECT  MAX(Dates) FROM TableName GROUP BY Username)


Username    Dates       value
bob         2010-02-02  1.2       
brad        2010-01-02  1.1       
fred        2010-01-03  1.0       

使用窗口函数(适用于Oracle, Postgres 8.4, SQL Server 2005, DB2, Sybase, Firebird 3.0, MariaDB 10.3)

select * from (
    select
        username,
        date,
        value,
        row_number() over(partition by username order by date desc) as rn
    from
        yourtable
) t
where t.rn = 1
SELECT t1.username, t1.date, value
FROM MyTable as t1
INNER JOIN (SELECT username, MAX(date)
            FROM MyTable
            GROUP BY username) as t2 ON  t2.username = t1.username AND t2.date = t1.date

下面是在SQL Server中只返回每个用户最近记录的一种方法:

WITH CTE AS (
  SELECT *, ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY date DESC) AS rn
  FROM your_table
)
SELECT *
FROM CTE
WHERE rn = 1;

这使用一个公共表表达式(CTE)为每个用户的每条记录分配一个唯一的rn(行号),基于user_id并按日期降序排序。最后一个查询只选择rn等于1的记录,这表示每个用户最近的记录。