64

我正在尝试从一个表中获取 ip、用户和最近的时间戳,该表可能同时包含用户的当前 ip 和一个或多个先前的 ip。我想为每个用户添加一行,其中包含最新的 ip 和相关的时间戳。因此,如果表如下所示:

username      |  ip      |  time_stamp  
--------------|----------|--------------  
ted           | 1.2.3.4  | 10  
jerry         | 5.6.6.7  | 12  
ted           | 8.8.8.8  | 30  

我希望查询的输出是:

jerry    |  5.6.6.7   |  12
ted      |  8.8.8.8   |  30  

我可以在单个 sql 查询中执行此操作吗?如果重要,DBMS 是 Postgresql。

4

6 回答 6

95

试试这个:

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
于 2009-07-16T20:26:33.570 回答
33

带有 ROW_NUMBER 窗口函数的漂亮优雅的解决方案(由 PostgreSQL 支持 - 请参阅SQL Fiddle):

SELECT username, ip, time_stamp FROM (
 SELECT username, ip, time_stamp, 
  ROW_NUMBER() OVER (PARTITION BY username ORDER BY time_stamp DESC) rn
 FROM Users
) tmp WHERE rn = 1;
于 2014-12-24T00:51:36.710 回答
8

像这样的东西:

select * 
from User U1
where time_stamp = (
  select max(time_stamp) 
  from User 
  where username = U1.username)

应该这样做。

于 2009-07-16T20:28:33.910 回答
3

以上两个答案都假设每个用户和时间戳只有一行。根据应用程序和 time_stamp 的粒度,这可能不是一个有效的假设。如果您需要处理给定用户的 time_stamp 关系,则需要扩展上面给出的答案之一。

在一个查询中写这个需要另一个嵌套的子查询 - 事情会开始变得更加混乱,性能可能会受到影响。

我很想将此添加为评论,但我还没有 50 名声望,很抱歉发布为新答案!

于 2013-08-13T09:50:02.363 回答
2

还不能发表评论,但@Cristi S 的回答对我来说是一种享受。

在我的场景中,我只需要在 Lowest_Offers 中为所有 product_id 保留最近的 3 条记录。

需要修改他的 SQL 以删除 - 认为这样可以,但语法错误。

DELETE from (
SELECT product_id, id, date_checked,
  ROW_NUMBER() OVER (PARTITION BY product_id ORDER BY date_checked DESC) rn
FROM lowest_offers
) tmp WHERE > 3;
于 2015-02-05T09:30:56.363 回答
0

我一直在使用它,因为我正在从另一个表返回结果。虽然我试图避免嵌套连接,如果它有助于少一步。那好吧。它返回相同的东西。

select
users.userid
, lastIP.IP
, lastIP.maxdate

from users

inner join (
    select userid, IP, datetime
    from IPAddresses
    inner join (
        select userid, max(datetime) as maxdate
        from IPAddresses
        group by userid
        ) maxIP on IPAddresses.datetime = maxIP.maxdate and IPAddresses.userid = maxIP.userid
    ) as lastIP on users.userid = lastIP.userid
于 2013-09-05T15:32:26.960 回答