【问题标题】:Aggregating Data with OVER PARTITION by date按日期聚合具有 OVER PARTITION 的数据
【发布时间】:2021-10-08 15:00:44
【问题描述】:

这个问题的继续: Postgresql: calculate share of total investment per investor, per day

从这个问题开始,我想要一个查询,它将根据多个投资者的数据为我提供每日统计数据。

例如,假设我有 4 位投资者,我想要将其中两个投资者的每日统计数据加起来。我最终会得到一个看起来像这样的表格:

date total_profit total_investment user_investment investment_share user_share user_profit
2021-01-01 500 10000 5000 50.00 38.2865 95.71625
2021-01-02 200 10000 5000 50.00 38.2865 38.2865
2021-01-03 185 15000 2500 16.66 16.3336 15.1085
2021-01-04 175 15000 3000 20.00 11.2478 9.8418
2021-01-05 229 15000 3000 20.00 11.2478 12.8787

下面是对每一列的描述:

日期:daily_stats表中利润对应的单个日期

total_profit:日期为daily_stats 行的利润列中的值

total_investment:当前日期所有投资的总价值

user_investment:所选用户在当前日期的投资总价值

investment_share:所选用户的投资“百分比”列的组合值,与投资金额成正比。我认为这个值的公式是:

(i.amount / (SUM(i.amount) over (partition by s.date))) * i.percent

例如,如果我正在查看两个用户的数据,每个用户在我的日期范围内都有一项投资,我必须像这样计算百分比列的组合值:

A B
1 amount percent
2 500 20
3 200 45

( (A2 / (A2 + A3) ) * B2) + ( (A3 / (A2 + A3) ) * B3)

或者

(B2 * A2 + B3 * A3) / (A2 + A3)

但我认为以当前查询的设置方式这样做可能会更加棘手。顺便说一句,我正在使用电子表格对此进行模拟,因此将其复制/粘贴到谷歌表格或其他内容中可能对您有用。

user_share:投资者将根据其组合投资规模获得的利润占总投资规模的百分比。

e.g. (500 + 200) / 15000 = user_share = 0.046 (4.6%)

user_profit 最后这只是 total_profit * investment_share * user_share

我确定我又犯了更多基本的数学错误,我不再因为疲劳而责备它,因为现在是午餐时间:P

这是更新的小提琴,对我需要的东西进行了一次糟糕的尝试:https://www.db-fiddle.com/f/m1DFJKzMs8SuYeVAUYcHU9/11

【问题讨论】:

  • 我迷路了。该表是您开始使用的数据吗?是你想要的结果吗?两者兼备真的很有帮助。
  • 表格是我想要的结果,数据可以在帖子底部的db-fiddle中找到。这篇文章实际上是上一个问题的延续,一个有用的用户建议我设置一个新问题。但非常感谢任何帮助!
  • 你是说你只想要 user_share 的 SUM 和 user_profit 列的 SUM (分别)每天超过指定的用户列表。这就是全部?我们可以将初始解决方案包装在 WITH clause 术语中并执行 SUM。

标签: php sql postgresql math


【解决方案1】:

原始查询已经为每个用户提供了每天的基本详细信息。无需重新计算该计算。只需将查询包装在 CTE 术语中即可。

以下是原始查询产生的列:

| date       | profit | user_id | amount | percent | total_inv | user_profit |

不清楚你想用百分比做什么。如果你记得那个值代表什么,我认为它不容易聚合。

类似这样的东西(使用 total_share):

WITH query1 AS (
  SELECT s.date, s.profit
       , i.user_id, i.amount, i.percent
       , SUM(i.amount) OVER (PARTITION BY s.date) AS total_inv
       , ROUND(s.profit * (i.percent / 100.0) * i.amount / SUM(i.amount) OVER (PARTITION BY s.date), 2) AS user_profit
       , ROUND((1.0 * i.amount / (SUM(i.amount) over (partition by s.date))) * i.percent, 2) AS user_share
    FROM daily_stats AS s
    JOIN investments AS i
      ON s.date BETWEEN i.start_date AND i.end_date
   WHERE s.date BETWEEN '2021-02-01' AND '2021-02-05'
     )
SELECT date
     , MAX(profit) AS profit
     , MAX(total_inv) AS total_inv
     , SUM(user_profit) AS total_profit
     , SUM(user_share) AS total_share
  FROM query1
 WHERE user_id IN (1, 4)
 GROUP BY date
;

来自小提琴的结果:

工作测试用例: Test case with PG V3

在此处更新了您的测试用例: Your test case updated

【讨论】:

  • 我没有包括新的 user_share 计算。但这应该很容易添加。
  • @Dioralop user_share / 包括总计算。我认为您的 user_share 示例计算可能不正确。我相信您错过了该用户的百分比乘法。请随意解释。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-10-30
  • 2020-09-22
  • 1970-01-01
  • 2021-02-05
  • 1970-01-01
  • 2021-06-16
  • 1970-01-01
相关资源
最近更新 更多