SQL查询以获取给定密钥的每个实例的最近行
我试图从一个表可能包含一个用户的当前IP和一个或多个以前的IPS获取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。
尝试这个:
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
使用ROW_NUMBER窗口函数的漂亮优雅的解决scheme(由PostgreSQL支持 – 参见SQL小提琴 ):
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;
像这样的东西:
select * from User U1 where time_stamp = ( select max(time_stamp) from User where username = U1.username)
应该这样做。
上述两个答案都假定每个用户和time_stamp只有一行。 根据应用程序和time_stamp的粒度,这可能不是一个有效的假设。 如果您需要处理给定用户的time_stamp关系,则需要扩展上面给出的答案之一。
要在一个查询中写这个会需要另一个嵌套的子查询 – 事情会变得更加混乱,性能可能受到影响。
我本来希望把这个作为一个评论添加,但是我还没有50个声望,所以很抱歉张贴为一个新的答案!
不能发表评论,但@Cristi S的答案对我来说是一种享受。
在我的情况下,我只需要在Lowest_Offers中保留所有product_ids的最近3条logging。
需要重做他的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;
我一直在使用这个,因为我从另一个表返回结果。 虽然我试图避免嵌套连接,如果它有助于减less一步。 好吧。 它返回相同的东西。
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