我有一张这样的桌子:
table1

+----+-----+------+
| id | seq | test |
+----+-----+------+
|  1 |   1 | HR   |
|  1 |   2 | RR   |
|  2 |   1 | HR   |
|  2 |   2 | RR   |
|  2 |   3 | OXY  |
|  3 |   1 | HR   |
|  3 |   2 | RR   |
|  4 |   1 | HR   |
|  4 |   2 | RR   |
|  4 |   3 | OXY  |
+----+-----+------+

我想得到如下的结果表。也就是说,只有当一个特定id的所有三个序列号都存在时,我才需要拥有该特定id的所有行:
+----+-----+------+
| id | seq | test |
+----+-----+------+
|  2 |   1 | HR   |
|  2 |   2 | RR   |
|  2 |   3 | OXY  |
|  4 |   1 | HR   |
|  4 |   2 | RR   |
|  4 |   3 | OXY  |
+----+-----+------+

我期待着写一个plpgsql函数给我的解决方案。我对plpgsql和编程还比较陌生。如果有人帮我弄到结果那就太好了。
到目前为止,这是我的函数,它是不完整的:
CREATE OR REPLACE FUNCTION test()
returns SETOF table1 AS $$
DECLARE
    cur CURSOR FOR
        SELECT *
        FROM table1
        ORDER by id;
    rec_cur RECORD;
    counter INTEGER DEFAULT 0;

BEGIN
    OPEN cur;

    FETCH FIRST FROM cur INTO rec_cur;
    MOVE RELATIVE +1 FROM cur;

    LOOP
        FETCH cur INTO rec_cur;
        EXIT WHEN NOT FOUND;

        IF rec_cur.seq = 1 AND counter = 0 THEN
        RETURN NEXT rec_cursor;
        END IF;

    END LOOP;
    CLOSE cur;
    RETURN;

END ; $$
LANGUAGE PLPGSQL STABLE PARALLEL SAFE;

最佳答案

光标绝对不是正确的方法。您可以很容易地使用聚合和having

select id
from t
where seq in (1, 2, 3)
group by id
having count(seq) = 3;

然后,要获取原始行,有多种方法:
select t.*
from t join
     (select id
      from t
      where seq in (1, 2, 3)
      group by id
      having count(seq) = 3
     ) tt
     on t.id = tt.id;

编辑:
如果序列号始终从1开始且没有间隙,则可以使用窗口函数:
select t.*
from (select t.*, max(t.seq) over (partition by t.id) as maxseq
      from t
     ) t
where maxseq = 3;

10-01 04:54
查看更多