对于多个表的循环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
【问题讨论】:
我本来打算试试这个的,但是你的桌子转换成INSERT
s 简直就是一场噩梦。您是否有机会提供更少“漂亮”、更多功能的数据?最好是 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的主要内容,如果未能解决你的问题,请参考以下文章