【问题标题】:PostgreSQL - Filter column 2 results based on column 1PostgreSQL - 根据第 1 列过滤第 2 列结果
【发布时间】:2016-08-21 03:17:49
【问题描述】:

请原谅一个新手问题。我是 postgresql 新手。

我有一个充满交易信息的数据库。我的目标是遍历自第一次交易以来的每一天,并显示当天或前 30 天内有多少独立用户进行了购买。

因此,2016 年 2 月 1 日的唯一身份用户数应该显示从 2016 年 1 月 1 日到 2016 年 2 月 1 日的所有唯一身份用户。 2016 年 2 月 2 日的唯一身份用户数应显示 2016 年 1 月 2 日至 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;

如您所见,我不知道如何引用第一列中存在的内容来指定过滤器中应包含的日期范围。

任何帮助将不胜感激!

【问题讨论】:

  • 你能在sqlfiddle.com上添加架构和一些示例数据吗?
  • @MarekSkiba 刚刚添加。如果可以,请尝试一下!谢谢!

标签: sql-server postgresql


【解决方案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

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

【讨论】:

  • 非常感谢!它给出了我正在寻找的结果。绝对让我走上正轨。不幸的是,我正在使用一个非常大的数据集,所以这非常慢(对于 LIMIT 10 查询>10 分钟)。对优化有什么想法吗?
猜你喜欢
  • 2023-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多