对于多个表的循环postgres

Posted

技术标签:

【中文标题】对于多个表的循环postgres【英文标题】:For loop postgres over multiple tables 【发布时间】:2014-02-10 23:11:58 【问题描述】:

您好,我在 postgres 中有两个表,它们的结构相似,如下所示

表 A

╔═══════════════════════════════════════════════════╗
║ id | timestamp                |  type | category  ║
╠═══════════════════════════════════════════════════╣
║ 1  | 2014-02-11 01:10:34.1234 | A  | 1            ║
║ 2  | 2014-02-11 01:10:36.7533 | A  | 2            ║
║ 3  | 2014-02-11 01:10:39.914  | E  | 1            ║
║ 4  | 2014-02-11 01:10:42.6712 | E  | 3            ║
║ 5  | 2014-02-11 01:10:34.9123 | E  | 1            ║
║ 6  | 2014-02-11 01:10:36.0313 | C  | 2            ║
║ 7  | 2014-02-11 01:10:39.1234 | X  | 1            ║
║ 7  | 2014-02-11 01:10:40.6743 | X  | 1            ║
║ 8  | 2014-02-11 01:10:42.9092 | B  | 3            ║
║ 9  | 2014-02-11 01:10:43.8234 | T  | 1            ║
║ 10 | 2014-02-11 01:10:45.1566 | T  | 1            ║
║ 11 | 2014-02-11 01:10:58.7344 | T  | 1            ║
║ 12 | 2014-02-11 01:10:59.9232 | T  | 1            ║
║ 13 | 2014-02-11 01:10:59.9232 | T  | 3            ║
║ 14 | 2014-02-11 01:10:59.9232 | T  | 2            ║
║ 15 | 2014-02-11 01:10:59.9232 | T  | 2            ║
╚═══════════════════════════════════════════════════╝

表 B

╔═══════════════════════════════════════════════════╗
║ id | timestamp                |  type | category  ║
╠═══════════════════════════════════════════════════╣
║ 1  | 2014-02-11 01:10:34.123  | A  | 1            ║
║ 2  | 2014-02-11 01:10:35.9092 | A  | 2            ║
║ 3  | 2014-02-11 01:10:36.1234 | E  | 1            ║
║ 4  | 2014-02-11 01:10:40.0100 | E  | 3            ║
║ 5  | 2014-02-11 01:10:51.1234 | E  | 2            ║
║ 7  | 2014-02-11 01:10:54.5347 | X  | 1            ║
║ 8  | 2014-02-11 01:11:02.7914 | B  | 3            ║
║ 9  | 2014-02-11 01:11:03.9000 | T  | 1            ║
║ 10 | 2014-02-11 01:11:05.7829 | T  | 1            ║
║ 11 | 2014-02-11 01:11:06.125  | T  | 1            ║
║ 12 | 2014-02-11 01:11:10.0000 | T  | 1            ║
║ 13 | 2014-02-11 01:10:59.9232 | T  | 3            ║
║ 14 | 2014-02-11 01:10:59.9232 | T  | 2            ║
╚═══════════════════════════════════════════════════╝

我想在存储过程中比较的是给定 type 的最后 5 条记录,如果最后 5 条记录在 category 字段上匹配而不是成功如果连一个都没有,那么这一切都是失败的。

对类型和时间戳进行连接很诱人,但是表上的时间戳永远不会准确,因为第二个表的数据来自外部系统。 (在这种情况下无法使用 NTP)

例如

    在上表中,类型 A 和 B 是成功的,因为它们具有完全相同的最后 5 条记录,它们是相同顺序的同一类别,即使它们总共没有 5 条。

    E 失败,因为它们都有 3 条记录,但第二个表的最后一个类别是 2 而不是 1。

    C 失败,因为它在表 B 中不存在

    T 失败,因为最后 5 个不匹配。

我希望将这两个数据集作为独立数组返回,而不是通过一个 for 循环和一个索引来比较各个字段,但是在 postgres 中没有看到以这种方式使用的数组,请指出正确的方向。

所有 postgres 示例似乎都循环遍历单个表的记录。

example 1

example 2

postgres doc

【问题讨论】:

我本来打算试试这个的,但是你的桌子转换成INSERTs 简直就是一场噩梦。您是否有机会提供更少“漂亮”、更多功能的数据?最好是 sqlfiddle.com 或与其“文本到 ddl”工具兼容的东西。 (完成后在此处编辑您的问题和评论)。还有,PostgreSQL 版本? 【参考方案1】:

这是一个 SQL 查询,它可以在没有存储过程的情况下为您提供结果:

select ta.type, case when ta.str_agg = tb.str_agg then 'success' else 'failed' end
from
(select type, array_to_string(array_agg(category order by timestamp desc), ',') as str_agg
from (select * from table_a as t where t.id in (select id from table_a WHERE type = t.type order by timestamp desc  LIMIT 5)) as t1
group by type) as ta
LEFT JOIN
(select type, array_to_string(array_agg(category order by timestamp desc), ',') as str_agg
from (select * from table_b as t where t.id in (select id from table_b WHERE type = t.type order by timestamp desc  LIMIT 5)) as t1
group by type) as tb
ON (ta.type = tb.type)

test here

【讨论】:

谢谢,但是当它应该失败时,C 并没有失败。只需将其从 JOIN 更改为 left Join,现在它就可以正常工作了。非常感谢 感谢尝试编辑您的答案,但我需要更改超过 6 个字符。

以上是关于对于多个表的循环postgres的主要内容,如果未能解决你的问题,请参考以下文章

循环遍历多个表的 plsql 代码

多个多对多关系(循环关系)

链表的循环删除

使用选择而不是表的游标循环(Oracle)

csharp 对于具有多个更新的循环。

csharp 对于具有多个更新的循环。