遍历行,将它们相互比较,并将结果存储在另一个表中

时间:2013-03-13 15:27:36

标签: postgresql iteration

我有一个包含以下行的表:

product_id | order_date
A          | 12/04/12
A          | 01/11/13
A          | 01/21/13
A          | 03/05/13
B          | 02/14/13
B          | 03/09/13

我现在需要的是每个月的概述,第一次购买了多少产品(=前一个月没有购买),现有产品有多少(=前一个月已购买)和有多少人在一个月内没有购买。将上面的示例作为输入,无论数据中的时间段如何,脚本都应提供以下结果:

month   | new | existing | nopurchase
12/2012 | 1   | 0        | 0
01/2013 | 0   | 1        | 0
02/2013 | 1   | 0        | 1
03/2013 | 1   | 1        | 0

很高兴得到第一个暗示如何解决这个问题,这样我才能继续。

谢谢!

1 个答案:

答案 0 :(得分:0)

SQL Fiddle

with t as (
    select product_id pid, date_trunc('month', order_date)::date od
    from t
    group by 1, 2
)
select od,
    sum(is_new::integer) "new",
    sum(is_existing::integer) existing,
    sum(not_purchased::integer) nopurchase
from (
    select od,
        lag(t_pid) over(partition by s_pid order by od) is null and t_pid is not null is_new,
        lag(t_pid) over(partition by s_pid order by od) is not null and t_pid is not null is_existing,
        lag(t_pid) over(partition by s_pid order by od) is not null and t_pid is null not_purchased
    from (
        select t.pid t_pid, s.pid s_pid, s.od
        from
            t
            right join
            (
                select pid, s.od
                from
                    t
                    cross join
                    (
                        select date_trunc('month', d)::date od
                        from
                        generate_series(
                            (select min(od) from t),
                            (select max(od) from t),
                            '1 month'
                        ) s(d)
                    ) s 
                group by pid, s.od
            ) s on t.od = s.od and t.pid = s.pid
    ) s
) s
group by 1
order by 1