在PostgreSQL中为每个客户选择最后两条记录

时间:2011-10-21 07:27:17

标签: sql postgresql

有人能告诉我以下情况的查询吗? 我在表access_log中有这些列:

customer_id |  service_name | accessed_time

客户可能已经在任何时间访问过该服务。但我只需列出每个customer_id的最后两个记录。

2 个答案:

答案 0 :(得分:11)

Window functions救援(再次):

select customer_id, service_name, accessed_time
from (
    select customer_id, service_name, accessed_time,
           rank() over (partition by customer_id order by accessed_time desc) as rank
    from access_log
) dt
where dt.rank <= 2

这假定“最后两个”意味着“最近的两个”。 row_number窗口函数可能更合适,具体取决于您希望如何处理重复项。

鉴于这样的数据(对不起,我今晚感觉不到那么富有想象力):

=> select * from access_log order by customer_id, accessed_time;
 customer_id | service_name |    accessed_time    
-------------+--------------+---------------------
           1 | one          | 2011-01-01 00:00:00
           1 | two          | 2011-01-02 00:00:00
           1 | three        | 2011-01-03 00:00:00
           2 | two          | 2011-01-02 00:00:00
           2 | one          | 2011-04-01 00:00:00
           2 | three        | 2011-05-03 00:00:00

以上查询得出:

 customer_id | service_name |    accessed_time    
-------------+--------------+---------------------
           1 | three        | 2011-01-03 00:00:00
           1 | two          | 2011-01-02 00:00:00
           2 | three        | 2011-05-03 00:00:00
           2 | one          | 2011-04-01 00:00:00

答案 1 :(得分:5)

这些方面应该有效:

select * from access_log a1
where 2 > (select count(*) from access_log a2
           where a1.customer_id = a2.customer_id
           and a1.accessed_time < a2.accessed_time)

这将读取:获取同一客户存在0或1个其他访问日志的所有日志,以及稍后的“accessible_time”。确保在相关列上有适当的索引。