使用 cte 和子查询过滤最后一个值不是 status = 'cancel' 的地方

问题描述 投票:0回答:1
CREATE TABLE origin_polis (
    cif INT,
    no_polis TEXT,
    status TEXT,
    tgl_produksi DATE,
    tgl_awal DATE,
    tgl_akhir DATE
);
INSERT INTO origin_polis (cif, no_polis, status, tgl_produksi, tgl_awal, tgl_akhir)
VALUES
    (100, 'aaa', 'new', '2020-01-13', '2019-02-19', '2022-05-16'),
    (100, 'aaa', 'extend', '2020-01-13', '2020-01-19', '2023-03-13'),
    (100, 'aab', 'new', '2020-01-15', '2020-01-20', '2023-03-15'),
    (101, 'aba', 'new', '2019-05-17', '2019-01-25', '2023-01-15'),
    (101, 'abb', 'new', '2021-06-18', '2020-06-24', '2023-01-10'),
    (102, 'abc', 'new', '2021-01-15', '2021-01-13', '2022-01-13'),
    (102, 'abc', 'extend', '2022-01-17', '2022-01-15', '2023-01-13'),
    (102, 'abc', 'cancel', '2022-01-17', '2022-01-15', '2023-01-13'),
    (103, 'abd', 'new', '2022-04-19', '2022-03-15', '2023-01-14'),
    (103, 'abd', 'cancel', '2022-04-19', '2022-03-15', '2023-01-14'),
    (103, 'abe', 'new', '2022-06-25', '2022-07-10', '2023-01-29'),
    (104, 'aca', 'new', '2022-01-02', '2022-01-01', '2023-09-04'),
    (104, 'aca', 'change', '2022-01-04', '2022-01-01', '2023-09-04'),
    (104, 'aca', 'cancel', '2022-01-06', '2022-01-01', '2023-09-04'),
    (104, 'aca', 'renew', '2022-01-10', '2022-01-01', '2023-10-04'),
    (104, 'acb', 'new', '2022-01-04', '2022-01-02', '2023-10-05'),
    (105, 'ada', 'new', '2022-02-02', '2022-02-01', '2023-08-04'),
    (105, 'ada', 'change', '2022-02-04', '2022-02-01', '2023-08-04'),
    (105, 'ada', 'cancel', '2022-02-06', '2022-02-01', '2023-08-04'),
    (105, 'ada', 'renew', '2022-02-10', '2022-02-01', '2023-09-08'),
    (105, 'ada', 'cancel', '2022-02-11', '2022-02-01', '2023-09-08'),
    (105, 'ada', 'renew', '2022-02-13', '2022-02-10', '2023-10-09'),
    (105, 'ada', 'change', '2022-02-15', '2022-02-10', '2023-11-10');

我想在 PostgreSQL 中进行查询,所以输出是

到岸价格 无城邦 状态 tgl_产品 tgl_awal tgl_akhir
104 阿卡 2022-01-02 2022-01-01 2023-09-04
104 阿卡 改变 2022-01-04 2022-01-01 2023-09-04
104 阿卡 取消 2022-01-06 2022-01-01 2023-09-04
104 阿卡 续订 2022-01-10 2022-01-01 2023-10-04
105 阿达 改变 2022-02-04 2022-02-01 2023-08-04
105 阿达 取消 2022-02-06 2022-02-01 2023-08-04
105 阿达 续订 2022-02-10 2022-02-01 2023-09-08
105 阿达 取消 2022-02-11 2022-02-01 2023-09-08
105 阿达 续订 2022-02-13 2022-02-10 2023-10-09
105 阿达 改变 2022-02-15 2022-02-10 2023-11-10

获得所需输出的规则:

  1. 选择其中存在 status = 'cancel' 的 no_polis 列
  2. 之后,过滤最后一个 tgl_produksi 不是 status = 'cancel' 的地方

获取第一条规则:

select *
from origin_polis t1
where exists (select *
            from origin_polis t2
            where t1.no_polis = t2.no_polis
            and status = 'cancel');

如何将第二条规则包含在查询中, 第一条规则完成,然后用第二条规则再次过滤?

sql postgresql subquery common-table-expression
1个回答
0
投票

您的描述有些缺乏,但从数据和结果来看,似乎希望将规则应用于(cif,no_polis)的组合。如果这是不正确的,那么您需要大幅更新问题。

您可以通过以下方式获得:(请参阅演示

with last_cancel(cif, no_polis, tgl_produksi) as
     (select cif, no_polis, max(tgl_produksi)                       -- Rule 1: exists a status 'cancel'; get the last such status                         
        from origin_polis 
       where status = 'cancel'
       group by cif, no_polis 
     ) --select * from last_cancel;
select *
  from origin_polis op
  where (op.cif, op.no_polis) in (select lc.cif, lc.no_polis         -- Rule 2: Identify rows with a later non 'cancel' status         
                                    from last_cancel lc
                                   where lc.cif  = op.cif
                                     and lc.no_polis = op.no_polis
                                     and exists (select null             
                                                   from origin_polis t3
                                                  where (t3.cif, t3.no_polis) = (lc.cif, lc.no_polis)
                                                    and t3.status <> 'cancel'
                                                    and t3.tgl_produksi > lc.tgl_produksi
                                                )  
                                 )  
order by op.cif, op.no_polis, op.tgl_produksi;

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