微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

选择最后插入的包含标签的元素

如何解决选择最后插入的包含标签的元素

很长一段时间以来,我一直在努力从 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;

这样做的主要问题是,当给定的上下文文字出现在两个不同的上下文中时,此查询将返回两个事件,但我只想要一个。我想要每个 Nclient_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 举报,一经查实,本站将立刻删除。