SQL 省略初始记录直到列值大于零

问题描述 投票:0回答:3

我在 Postgres 中有一张名为

personal_profit
的表,如下所示:

约会 利润
2022-09-22 4000
2022-04-25 5000
2022-01-10 0
2022-02-14 0
2022-04-12 2000
2022-05-06 1000
2022-06-13 0

我想获得按月排序的总利润,但从利润大于零的月份开始。下面的查询省略了所有不满足我条件的利润为零的记录。我只想查询从 04/2022 月份开始。

Select distinct date_trunc('month', P.date) as profit_month, SUM(P.profit) as total_profit
from personal_profit P
group by profit_month
having SUM(P.profit) > 0
order by profit_month;
约会 利润
2022-04 7000
2022-05 1000
2022-06 0
2022-09 4000
sql postgresql window-functions
3个回答
1
投票

因为您想从哪里开始,按日期排序,所以有一个非零值,您可以简单地将其添加为 where 条件:

Select distinct date_trunc('month', P.date) as profit_month, SUM(P.profit) as total_profit
from personal_profit  p
where date >= (select date from personal_profit where profit >0 order by date limit 1 )
group by profit_month
order by profit_month;

演示小提琴


1
投票

条件“从利润大于零的月份开始”本质上是“从头开始跳过最长的零子序列”。这可以通过选择运行总计非零的月份或通过子查询来实现。我认为第一种方式更容易理解:

with personal_profit (date,profit) as (values
  (date '2022-09-22', 4000),
  (date '2022-04-25', 5000),
  (date '2022-01-10', 0),
  (date '2022-02-14', 0),
  (date '2022-04-12', 2000),
  (date '2022-05-06', 1000),
  (date '2022-06-13', 0)
)
, grouped as (
  select date_trunc('month', P.date) as profit_month
       , sum(P.profit) as total_profit
       , sum(sum(P.profit)) over (order by date_trunc('month', P.date)) as running_total
  from personal_profit P
  group by profit_month
)
select profit_month, total_profit
from grouped
where running_total > 0
order by profit_month;
profit_month 总利润
2022-04-01 00:00:00+01 7000
2022-05-01 00:00:00+01 1000
2022-06-01 00:00:00+01 0
2022-09-01 00:00:00+01 4000
SELECT 4

小提琴

注意

running_total
表达式在理想世界中应该读作
sum(total_profit) over (order by profit_month)
,但是 Postgres 不知道同一个
select
子句中的别名(甚至
group by <alias_from_select_clause>
是 Postgres 的糖,对于其他数据库供应商来说是不寻常的)。


0
投票

您可以检查第一个超过 0 的月份,并使用它来过滤所有值

Select to_char(P."date", 'YYYY-MM') as profit_month, SUM(P.profit) as total_profit
from personal_profit P

group by profit_month
having to_char(P."date", 'YYYY-MM') >= (Select  
 DISTINCT  MIN(
  to_char(P."date", 'YYYY-MM')
  ) over() as min_month
from personal_profit P
GROUP BY to_char(P."date", 'YYYY-MM')
having SUM(P.profit) > 0
)
order by profit_month;

profit_month 总利润
2022-04 7000
2022-05 1000
2022-06 0
2022-09 4000
SELECT 4

小提琴

© www.soinside.com 2019 - 2024. All rights reserved.