简体   繁体   English

Pgsql-如何使用 pgsql 过滤报告天数?

[英]Pgsql- How to filter report days with pgsql?

Let's say I have a table Transaction which has data as following:假设我有一个表事务,其数据如下:


Transaction交易

| id         | user_id     | amount      | created_at   |
|:-----------|------------:|:-----------:| :-----------:|
|    1       |        1    |     100     |  2021-09-11  |  
|    2       |        1    |     1000    |  2021-09-12  |
|    3       |        1    |     -100    |  2021-09-12  |
|    4       |        2    |     200     |  2021-10-13  |
|    5       |        2    |     3000    |  2021-10-20  |
|    6       |        3    |     -200    |  2021-10-21  |
  • I want to filter this data by this: last 4days, 15days, 28days :我想通过以下方式过滤此数据:过去 4 天、15 天、28 天

Note: If user click on select option 4days this will filter last 4 days.注意:如果用户单击选择选项 4days,这将过滤过去 4 天。

I want this data我想要这个数据

  1. total commission (sum of all transaction amount * 5%)总佣金(所有交易金额之和*5%)
  2. Total Top up总充值
  3. Total Debut: which amount (-)总出道:多少(-)

Please help me out and sorry for basic question!请帮帮我,对基本问题感到抱歉!

Expect result:期待结果:

** If user filter last 4days: ** 如果用户筛选过去 4 天:

Let's say current date is: 2021-09-16假设当前日期是:2021-09-16

So result:所以结果:

- TotalCommission (1000 - 100) * 5
- TotalTopUp: 1000
- TotalDebut: -100

I suspect you want:我怀疑你想要:

SELECT SUM(amount) * 0.05 AS TotalCmomission,
       SUM(amount) FILTER (WHERE amount > 0) AS TotalUp,
       SUM(amount) FILTER (WHERE amount < 0) AS TotalDown
FROM t
WHERE created_at >= CURRENT_DATE - 4 * INTERVAL '1 DAY';

This assumes that there are no future created_at (which seems like a reasonable assumption).这假设没有未来的created_at (这似乎是一个合理的假设)。 You can replace the 4 with whatever value you want.您可以将4替换为您想要的任何值。

Take a look at the aggregate functions sum , max and min .查看聚合函数summaxmin Last four days should look like this:最后四天应该是这样的:

SELECT 
  sum(amount)*.05 AS TotalComission,
  max(amount) AS TotalUp,
  min(amount) AS TotalDebut
FROM t
WHERE created_at BETWEEN CURRENT_DATE-4 AND CURRENT_DATE;

Demo: db<>fiddle演示: db<>fiddle

Your description indicates specifying the number of days to process and from your expected results indicate you are looking for results by user_id (perhaps not as user 1 falls into the range).您的描述表明指定要处理的天数,并且从您的预期结果表明您正在按 user_id 查找结果(可能不是因为用户 1 属于该范围)。 Perhaps the the best option would be to wrap the query into a SQL function.也许最好的选择是将查询包装到 SQL 函数中。 Then as all your data is well into the future you would need to parameterize that as well.然后,由于您的所有数据都可以用于未来,因此您也需要对其进行参数化。 So the result becomes:所以结果变成了:

create or replace 
function Commissions( user_id_in     integer default null
                    , days_before_in integer default 0
                    , end_date_in    date    default current_date
                    )
 returns table( user_id         integer
              , totalcommission numeric
              , totalup         numeric
              , totaldown       numeric
              ) 
 language sql
as $$
    select user_id 
         , sum(amount) * 0.05
         , sum(amount) filter (where amount > 0) 
         , sum(amount) filter (where amount < 0) 
      from transaction
     where (user_id = user_id_in or user_id_in is null) 
       and created_at <@ daterange( (end_date_in - days_before_in * interval '1 day')::date 
                                  , end_date_in
                                  , '[]'::text          -- indicates inclusive of both dates
                                  )
    group by user_id;
$$; 

See demo here . 在这里查看演示 You may just want to play around with the parameters and see the results.您可能只想使用参数并查看结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM