Postgres 查询总计数按月和年分组

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

以下是数据表 -

 del_no  |   Pkt   | direction  |  Env  | start_datetimestamp |
---------+---------+------------+-------+---------------------+
 H_00002 |  02     |  SOUTH     | PROD  | 2022-10-29 16:20:57 |
 E20     |  20     |  NORTH     | PROD  | 2022-10-30 16:41:37 |
 H_00002 |  02     |  NORTH     | TEST  | 2022-10-30 17:21:17 |
 E20     |  20     |  SOUTH     | DEV   | 2022-10-30 17:30:24 |
 H_00004 |  02     |  NORTH     | PROD  | 2022-10-30 16:52:48 |
 H_00004 |  02     |  SOUTH     | PROD  | 2022-10-30 19:03:36 |
 H_00007 |  02     |  NORTH     | PROD  | 2022-10-30 20:52:48 |
 H_00007 |  02     |  SOUTH     | PROD  | 2022-10-30 21:03:36 |
 H_00015 |  02     |  SOUTH     | TEST  | 2022-11-13 19:11:10 |
 L 0013  |  13     |  NORTH     | PROD  | 2022-11-14 20:06:46 |
 H_00015 |  02     |  NORTH     | TEST  | 2022-11-15 20:17:40 |
 L0021   |  21     |  SOUTH     | TEST  | 2022-11-15 20:56:18 |
 H_00015 |  02     |  NORTH     | PROD  | 2022-11-15 20:17:40 |
 L0027   |  21     |  SOUTH     | DEV   | 2022-11-30 20:56:18 |
 H_00019 |  02     |  NORTH     | PROD  | 2022-11-30 20:17:40 |
 L0023   |  21     |  SOUTH     | TEST  | 2022-11-30 20:56:18 |
 H_00019 |  02     |  SOUTH     | TEST  | 2022-11-30 20:17:40 |
 L0025   |  21     |  SOUTH     | TEST  | 2022-11-30 20:56:18 |
 H_00019 |  02     |  SOUTH     | DEV   | 2022-11-30 20:17:40 |
 H_00018 |  02     |  SOUTH     | PROD  | 2023-10-31 20:17:40 |
 H_00018 |  02     |  NORTH     | PROD  | 2023-11-02 03:17:40 |

我想计算以下条件下的回合数 -

1- 按 Pkt 过滤,仅 Pkt = 02。
2- 按 'del_no' 分组(将 NORTH 和 SOUTH 视为一个完整的回合),然后按月和每年对所有回合进行计数。
3- 根据 Env 分离计数。 (例如,第一行和第三行是一轮完整的回合,并且都有 PROD 和 TEST 环境,因此一个计数应该在 PROD/TEST 环境中,其他也同样)。
4-如果相同的del_no(H_00018)在另一个月份开始并在下个月结束,那么计数应该在开始月份添加。

输出-

Month   |       Env     | Counts |
--------+---------------+--------+
2022-10 | PROD/TEST     |  1     |
2022-10 | PROD          |  2     |
2022-11 | PROD/TEST     |  1     |
2022-11 | PROD/TEST/DEV |  1     |
2023-10 | PROD          |  1     |

以下查询不适用于第四个条件 -

select "Month",sum(rounds)"Counts","Env" from (
    select del_no,
           to_char(start_datetimestamp,'YYYY-MM') "Month",
           least( count(*)filter(where direction='SOUTH')
                 ,count(*)filter(where direction='NORTH')) rounds,
           string_agg(distinct env,'/' order by env) "Env"
    from tablename where pkt='2' group by del_no,2)
group by "Month","Env";

https://dbfiddle.uk/FGIzl6hy

postgresql group-by gaps-and-islands
1个回答
0
投票

您可以使用多个 CTE :

with cte as (
  select del_no
  from tableName
  where Pkt = '2'
  group by del_no
  having count(distinct direction) = 2
),
cte2 as (
  select to_char(min(start_datetimestamp), 'YYYY-MM') as _Month, t.del_no, Env
  from cte c
  inner join tableName t on c.del_no = t.del_no
  group by t.del_no, Env
),
cte3 as (
  select _Month, del_no, string_agg(distinct env, '/') as Env
  from cte2
  group by _Month, del_no
)
select _Month, env, count(env) as Counts 
from cte3
group by _Month, env
  • 第一个cte用于过滤掉任何不完整回合的del_no
  • 第二个 cte 用于获取每个 del_noEnv 的开始月份。
  • cte3 用于每月准备不同的环境。

演示在这里

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