如何创建一个循环来使用它作为PostgreSQL查询的过滤器?

ruarlubt  于 2023-04-29  发布在  PostgreSQL
关注(0)|答案(1)|浏览(99)

我一直在寻找一种方法来创建一个循环,使用一系列日期作为查询的过滤器,并将其结果插入另一个表中。
我试着调整一些我在其他主题上发现的查询,但没有成功。
我的想法是创建一个基于几个月的时间周期的循环,它将取代过滤器和JOIN的键。我需要单独执行此操作,因为我的原始表包含两个字段,需要为每个期间进行评估。
我已经尝试构建了一个我认为将在循环中使用的查询:

SELECT
      a.client_id 
    , COALESCE(b.batch,c.batch) batch
FROM
    table1 a
LEFT JOIN
    table2 b ON date_trunc('month',a.starts_at)::date = b.batch
LEFT JOIN
    table2 c ON date_trunc('month',a.ends_at)::date = c.batch
WHERE 
    date_trunc('month',a.received_at) >= b.batch - INTERVAL '1 month'
    AND date_trunc('month',a.received_at) < b.batch + INTERVAL '2 month'
    AND a.selection = 'GROUP 1'
    AND a.status = 'SUCCESS'

因此,每个batch都应该替换为月份级别的截断日期(例如:从“2022-01-01”至“2022-12- 01”)。目标是这个脚本每个月运行一次,将结果插入另一个表。
抱歉我没说清楚谁能帮我想出最好的方法来构建这个剧本?
如果需要更多的信息,请让我知道。
编辑1:正如阿德里安所问的,这里有一些关于table的规格。
表1:
client_id-用户标识(同一用户有多行)
received_at-添加寄存器的时间戳
starts_at-开始有效的时间戳
ends_at-有效期结束的时间戳
selectionstatus都是将应用的滤波器。
表2:
包含日期范围(batch)的表,该日期范围将用作循环的过滤器。如果它不起作用或不是最佳的,则可以更改。
编辑二:
你好,@AdrianKlaver!
我认为在过滤器上使用range函数的问题是,如果starts_atends_at时间戳在批处理上,我需要考虑一个寄存器。
示例:

id |      starts_at      |       ends_at       
----+---------------------+---------------------
  1 | 03/16/2023 01:12:00 | 04/15/2023 14:17:00

这种情况应在3月和4月批次中考虑。这就是为什么我在两个时间戳上使用了LEFT JOIN,并将它们组合在coalesce上。
你认为我们能采纳你的建议吗?
谢谢!

3qpi33ja

3qpi33ja1#

例如,使用范围包含运算符@>,其中运算符确定右侧的范围是否包含在左侧的范围中:

create table table1(id integer, starts_at timestamp, ends_at timestamp);

insert into table1 values 
  (1, '2023-04-01 01:12', '2023-04-19 14:17'), 
  (1, '2023-04-05 15:11', '2023-04-07 08:10'), 
  (2, '2023-04-11 16:45', '2023-04-25 02:30'), 
  (1, '2023-04-26 18:23', '2023-05-05 11:05');

select 
   id, starts_at, ends_at 
from 
   table1 
where 
   daterange('04/01/2023', '04/30/2023') @> daterange(starts_at::date, ends_at::date);
 id |      starts_at      |       ends_at       
----+---------------------+---------------------
  1 | 04/01/2023 01:12:00 | 04/19/2023 14:17:00
  1 | 04/05/2023 15:11:00 | 04/07/2023 08:10:00
  2 | 04/11/2023 16:45:00 | 04/25/2023 02:30:00

更新

将范围运算符更改为重叠测试&&,以检查两个范围是否具有重叠日期。

insert into table1 values (2, '2023-05-12', '2023-05-28');

select 
   id, starts_at, ends_at 
from 
   table1 
where 
   daterange('04/01/2023', '04/30/2023') && daterange(starts_at::date, ends_at::date);
 id |      starts_at      |       ends_at       
----+---------------------+---------------------
  1 | 04/01/2023 01:12:00 | 04/19/2023 14:17:00
  1 | 04/05/2023 15:11:00 | 04/07/2023 08:10:00
  2 | 04/11/2023 16:45:00 | 04/25/2023 02:30:00
  1 | 04/26/2023 18:23:00 | 05/05/2023 11:05:00

select                                                    
   id, starts_at, ends_at 
from 
   table1 
where 
   daterange('05/01/2023', '05/31/2023') && daterange(starts_at::date, ends_at::date);
 id |      starts_at      |       ends_at       
----+---------------------+---------------------
  1 | 04/26/2023 18:23:00 | 05/05/2023 11:05:00
  2 | 05/12/2023 00:00:00 | 05/28/2023 00:00:00

相关问题