2017-02-10 178 views
2

我想检索包含一年中每个月的最大时间戳的记录。postgresql查询 - 找到每个月的最大时间戳

为此,我从2016年1月至今的每个月都创建了一个临时表(date_series)。我想为每个月的每个ID找到最大时间戳,并显示相应的ID和状态。

这是我到目前为止有: 的createddate

with date_series as(
    SELECT * FROM generate_series('2016-01-01'::date, 
           now(), '1 month') 
) 
select max(a.created_at), a.id, d.generate_series, a.status 
from sales a, date_series d 
group by 2,3,4 

但是我不知道如何在逻辑结构上查询,以达到这些结果。

+0

我想我需要添加一个额外的子查询找到'MAX(a.created_at)'日期,然后加入与临时日期表。 – OAK

回答

1

阅读有关DISTINCT ONhttp://www.postgresqltutorial.com/postgresql-select-distinct/

试试这个

SELECT DISTINCT ON(a.id, a.status, date_trunc('month',cdate)) 
     a.id, 
     a.status, 
     date_trunc('month',cdate) "Month", 
     a.created_at 
FROM sales a 
ORDER BY a.id, a.status, date_trunc('month',cdate), created_at DESC 
1

假设你没有在你的一个月间隙(或不关心),以及时间戳是真正独一无二的,这应工作:

with salez as (
    select 
    id, status, created_at, 
    max (created_at) over (partition by date_trunc ('month', created_at)) as max_date 
    from 
    sales 
) 
select 
    max_date, id, date_trunc ('month', created_at)::date, status 
from salez 
where 
    max_date = created_at 

max的风险在于,如果你可以有两个记录完全相同的timesta mp,这会给你两个月的输出记录。如果这是可能的,并会破坏你的查询,使用row_number代替:

with salez as (
    select 
    id, status, created_at, 
    row_number() over (partition by date_trunc ('month', created_at 
     order by id desc)) as rn 
    from 
    sales 
) 
select 
    created_at, id, date_trunc ('month', created_at)::date, status 
from salez 
where 
    rn = 1 
+0

您的'按ID排序'不一定将row_number 1分配给每个分区的最大时间戳行,如OP请求。我建议像row_number()一样使用(由date_trunc分区('month',created_at)按照created_at desc分区)作为rn'。 – dnswlt