SQL查找最新日期,为什么我们需要'内连接'

时间:2016-04-27 12:21:16

标签: sql database

我试图使用SQL获取最新结果。我搜索了网站,发现了'stackoverflow'中的这篇旧帖子,链接:

SQL query to get most recent row for each instance of a given key

我在这里复制了最常被接受的答案。

Select u.[username]
      ,u.[ip]
      ,q.[time_stamp]
From [users] As u
Inner Join (
    Select [username]
          ,max(time_stamp) as [time_stamp]
    From [users]
    Group By [username]) As [q]
On u.username = q.username
And u.time_stamp = q.time_stamp

我不明白的是为什么我们不能简单地在下面使用(即:为什么在这种情况下需要'内连接'操作)?

Select username, ip, max(time_stamp) as time_stamp
    From users
    Group By username

2 个答案:

答案 0 :(得分:3)

大多数SQL变体(我认为MySQL除外)要求SELECT列表中的所有非聚合列也都在GROUP BY中。否则,对于具有多个username值的单个ip,哪一个应出现在结果中?在这种情况下,您可能知道用户名/ IP对是唯一的,但SQL引擎可能并不总是知道这一点,尤其是对于更复杂的查询。

通过一个例子澄清:

用户:

username      ip              timestamp
--------      --------------  ---------
bob           167.49.122.122  2016-01-05
john          167.49.122.123  2016-02-02
bob           167.49.122.124  2016-04-01

您期望看到什么结果?为“鲍勃”

应该是bob / 167.49.122.122 / 2016-04-01?鲍勃/ 167.49.122.124 / 2016年4月1日?既?

你可能会说,“好吧,显然我想要拥有最大日期的整行”,但是从你的第二个SELECT开始并不明显,即使它对人类来说似乎是直观的。

答案 1 :(得分:3)

您的语法建议SQL Server(或者MS Access,但我会乐观)。 ANSI标准SQL中的典型方法是使用row_number()

select u.*
from (select u.*,
             row_number() over (partition by username order by time_stamp desc) as seqnum
      from users u
     ) u
where seqnum = 1;

肯定还有其他方法,不需要明确的join