如何解决选择最后插入的包含标签的元素
很长一段时间以来,我一直在努力从 Postgresql 获取一组数据。
我在 Docker 中使用 Postgresql 11,表 events
包含:
Column | type | Modifiers
-----------|-----------|-------------
id | text | primary key
client_id | text | foreign key
created_at | timestamp | not null
context | []text | not null
目标是获取 client_id 子集的最后插入事件以及上下文子集。性能很重要,所以我只想使用 sql。
到目前为止,我使用 LAteraL
探索了一个解决方案,但效果不佳:
SELECT e2.*
FROM (
SELECT events.client_id,events.context
FROM events
WHERE
events.client_id IN (?) AND
events.context && ?
GROUP BY (events.client_id,events.context)
) e1 LEFT JOIN LAteraL (
SELECT *
FROM events
WHERE
events.client_id = e1.client_id AND
events.context = e1.context
ORDER BY events.created_at DESC LIMIT 1
) e2 ON true;
这样做的主要问题是,当给定的上下文文字出现在两个不同的上下文中时,此查询将返回两个事件,但我只想要一个。我想要每个 N
的 client_id
行,其中 N
介于 0(无事件)和参数中给定上下文的长度之间。
这些行的示例:
created_at | client_id | context
----------------| -------------|------------
5pm:15 | accb | ['home']
5pm:15 | baac | ['home']
5pm:20 | accb | ['home','shopping_cart']
5pm:25 | accb | ['shopping_cart','payment']
5pm:30 | accb | ['disconnect']
5pm:30 | baac | ['home','shopping_cart','payment']
5pm:35 | baac | ['disconnect']
使用参数 ['accb','baac']
用于客户端 ID 和 ['home','shopping_cart']
用于上下文,我想要的结果是:
created_at | client_id | context
----------------| -------------|------------
5pm:20 | accb | ['home','payment']
5pm:30 | baac | ['home','payment']
你有什么解决办法吗?
解决方法
如果您希望每个 client_id
一行,我建议 distinct on
:
select distinct on (e.client_id) e.*
from events e
where e.client_id in (?) and
e.context && ?
order by e.client_id,e.created_at desc;
,
一位同事找到了解决方案:
WITH ranked_events AS (
SELECT
events.*,ROW_NUMBER() OVER (PARTITION BY client_id ORDER BY created_at DESC) AS pos
FROM
events
WHERE
context @> ? AND
client_id IN (?)
)
SELECT
*
FROM
ranked_events
WHERE
pos = 1
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。