PostgreSQL - 根据第1列

时间:2016-08-19 20:40:48

标签: sql-server postgresql

原谅新手问题。我是postgresql的新手。

我有一个充满交易信息的数据库。我的目标是迭代自第一笔交易以来的每一天,并显示当天或之前30天内有多少独特用户购买。

因此2016年1月1日的独特用户数量应显示2016年1月1日至2016年1月2日期间所有独特用户。 2016年2月2日的独特用户数量应显示2016年2月1日至2016年2月2日期间所有独特用户。

以下是一些示例数据:http://sqlfiddle.com/#!15/b3d90/1

结果应该是这样的:

December 17 2014 -- 1
December 18 2014 -- 2
December 19 2014 -- 3
...
January 13 2015 -- 16
January 19 2015 -- 15
January 20 2015 -- 15
...

我提出的最好成绩如下:

SELECT
to_char(S.created, 'YYYY-MM-DD') AS my_day,
COUNT(DISTINCT 
    CASE
      WHEN S.created > S.created - INTERVAL '30 days'
      THEN S.user_id
      END)
FROM
    transactions S
GROUP BY my_day
ORDER BY my_day;

正如您所看到的,我不知道如何引用第一列中的内容以指定过滤器中应包含的日期范围。

非常感谢任何帮助!

1 个答案:

答案 0 :(得分:1)

我认为如果你进行自我加入,它会给你你想要的结果:

select
  t1.created,
  count (distinct t2.user_id)
from
  transactions t1
  join transactions t2 on
    t2.created between t1.created - interval '30 days' and t1.created
group by
  t1.created
order by
  t1.created

那就是说,我认为这将在后台进行笛卡尔连接,所以对于大型数据集,我怀疑它是非常有效的。如果遇到巨大的性能问题,有很多方法可以让它快得多......但在你解决这个问题之前,请先了解一下是否需要。

- 编辑8/20/16 -

回答你对此表现的问题......是的,这是一头猪。我承认。我在这里遇到了类似的问题:

PostgreSQL Joining Between Two Values

您的示例的相同概念是:

with xtrans as (
  select created, created + generate_series(0, 30) as create_range, user_id
  from transactions
)
select
  t1.created,
  count (distinct t2.user_id)
from
  transactions t1
  join xtrans t2 on
    t2.create_range = t1.created
group by
  t1.created
order by
  t1.created

它并不容易理解,但它应该产生相同的结果,只有它会明显更快,因为它没有做“美化的交叉连接。”