如何使用窗口功能仅在POSTGRES中选择高达某个值的行



我有一个名为test的下表,并且只想将其选择到相同id的第一个删除语句('1144QQT')上方的行。因此,从2021-03-01到2021-06-02(只有粗体)。因此,这将排除带有delete语句的行。它确实包括更多不同类型的id和更多相同类型的id。

表模式:

CREATE TABLE test(
id                BIGINT       PRIMARY KEY NOT NULL,
barcode_id        VARCHAR      NOT NULL,
date              DATE         NOT NULL,
keyword           VARCHAR      NOT NULL
);
INSERT INTO test
VALUES
(1, '1144QQT', '2021-03-01'::date, 'insert'),
(2, '1144QQT', '2021-03-01'::date, 'insert'),
(3, '1144QQT', '2021-03-01'::date, 'insert'),
(4, '1144QQT', '2021-03-01'::date, 'insert'),
(5, '1144QQT', '2021-03-01'::date, 'insert'),
(6, '1144QQT', '2021-03-01'::date, 'insert'),
(7, '1144QQT', '2021-03-01'::date, 'insert'),
(8, '1144QQT', '2021-03-01'::date, 'insert'),
(9, '1144QQT', '2021-03-01'::date, 'insert'),
(10, '1144QQT', '2021-03-01'::date, 'insert'),
(11, '1144QQT', '2021-03-01'::date, 'insert');
>strong>2021-03-01td style="text align:left;">611144QQT021-03-06删除入[/tr>2021-03-09调整除[/tr>
idbarcode_id日期关键字
111144QQT
211144QQT>调整
71144QQT2021-03-07
811144QQT2021-03-08
1011144QQT114477aTT2021-03-11

根据您的描述,这个逻辑似乎可以满足您的要求:

select t.*
from t
where t.id = '1144QQT' and t.keyword <> 'delete';

这就假设在删除之后没有id的行,但这似乎是合理的,并且与您的示例数据一致。

对于您的特定问题,有一种方法是关联子查询:

select t.*
from t
where t.id = '1144QQT' and
t.id < (select min(t2.date)
from t t2
where t2.id = t.id and
t2.keyword <> 'delete'
);

上述版本要求存在一个";删除"--根据你的问题,目前还不清楚这是否是一项要求。另一种选择使用窗口功能:

select t.*
from (select t.*,
min(date) filter (where keyword = 'delete') over (partition by id) as min_delete_date
where t.id = '1144QQT' 
) t
where date < min_delete_date;

如果你想要所有的行,如果没有";删除";,则将CCD_ 1添加到外部CCD_。

使用SUM()窗口函数用keyword = 'delete':识别第一行之前的行

SELECT id, date, keyword
FROM (
SELECT *, SUM((keyword = 'delete')::int) OVER (ORDER BY date) grp
FROM tablename
WHERE id = '1144QQT'
) t
WHERE grp = 0

请参阅演示
结果:

日期11144QQT11144QQT2021-03-02 00:00:00调整11144QQT2021-03-06 00:00:00调整

我只想把它选到同一id的第一条删除语句上方的一行。

NOT EXISTS()拯救:(注意date保留字,是列的坏名称)

SELECT *
FROM ztable zt
WHERE zt.zid = '1144QQT'
AND NOT EXISTS (
SELECT * FROM ztable nx
WHERE nx.zid = zt.zid
AND nx.zkeyword = 'delete'
AND nx.zdate <= zt.zdate
);

最新更新