有人能告诉我以下情况的查询吗?
我在表access_log
中有这些列:
customer_id | service_name | accessed_time
客户可能已经在任何时间访问过该服务。但我只需列出每个customer_id
的最后两个记录。
答案 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”。确保在相关列上有适当的索引。