2011-10-21 75 views
2

你们能否给我看看以下情况的查询? 我在表access_log这些列:在PostgreSQL中选择每个客户的最后两条记录

customer_id | service_name | accessed_time 

一位顾客可能会访问该服务的任何数量的时间。但是我只需要列出每个customer_id的最后两条记录。

+0

您是否正在寻找最后两个(即两个最最近)为每个'customer_id',无论'service_name'或是'service_name'涉及莫名其妙? –

+0

ya ..每个customer_id的两个最近记录,没关系service_name – Pavunkumar

回答

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,其他的访问日志为同一客户与后来的“accessed_time”的所有日志。确保在相关列上有适当的索引。

+0

WHERE子句的良好用法。从来没有想过任何类似的东西。 – bos

+0

@bos:谢谢。尽管如此,我认为*亩太短*的解决方案可能会超过我的 –

+0

测试它们并查看。 – Kuberchaun

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 
+0

不错!可能,您需要通过'customer_id,service_name'进行分区。 OP表达他们问题的方式,看起来这个统计数据应该是以每个客户和每个服务为基础的......? –

+0

@Lukas:OP会说“每个'customer_id'只有最后两条记录”,所以我不认为'service_name'进入它,除了要显示的东西。我会看看我能否得到澄清。 –

+0

嗯......我被* *中的“*可能访问过服务*”弄糊涂了 –

相关问题