Postgresql 如何获取每个组中所有列+每个组一个组计数列的最新记录?

Postgresql 如何获取每个组中所有列+每个组一个组计数列的最新记录?,postgresql,Postgresql,考虑下表: CREATE TABLE event( event_id UUID PRIMARY KEY, user_id UUID NOT NULL, trigger_id UUID NOT NULL, name VARCHAR (255) NOT NULL, type VARCHAR (50) NOT NULL, trigger_name VARCHAR (255) NOT NULL, status smallint, date_

考虑下表:

CREATE TABLE event(
    event_id UUID PRIMARY KEY,
    user_id UUID NOT NULL,
    trigger_id UUID NOT NULL,
    name VARCHAR (255) NOT NULL,
    type VARCHAR (50) NOT NULL,
    trigger_name VARCHAR (255) NOT NULL,
    status smallint,
    date_created TIMESTAMP NOT NULL DEFAULT NOW(),
);
我想

首先按类型ASC订购,然后按创建日期说明订购

这部分很容易做到

SELECT *
FROM event
WHERE user_id = 'fd80059a-3a16-40fe-9f6b-ad2812875d92'
ORDER BY type ASC, date_created DESC
2按触发器id、类型和名称分组,每组计数。是的,如果触发器id、类型和名称相同,我想创建一个组,并显示最近的一个组,其中包含组中所有事件的计数,即事件发生的次数,因为如果这3个相同,则可以认为事件相关

这是最具挑战性的部分。理想情况下,类似这样的方法会起作用:

SELECT * --, count(since the count/grouping is based on 3 columns, how??)
FROM event
WHERE account_id = 'fd80059a-3a16-40fe-9f6b-ad2812875d92'
ORDER BY type ASC, date_created DESC
GROUP BY trigger_id, type, name
将只给我每个组中的第一条记录,因为它们已按日期排序,但包含所有列,而不仅仅是GROUPBY子句中的列+最后的group count列

我现在使用选项1解决这个问题,然后在我的节点API中使用以下javascript代码,但是如果您理解这个代码片段,它正是我在postgres中需要做的事情:

[...arrayOfEventsFromDB.reduce((r, o) => {
    const key = `${o.trigger_id}-${o.type}-${o.name}`;

    const item = r.get(key) || Object.assign({}, o, {
      count: 0,
    });

    item.count++;

    return r.set(key, item);
  }, new Map).values()];
但在理想情况下,如果postgres非常适合这种聚合,我希望在SQL查询中使用它

编辑

因为我无法将注释中的代码粘贴到答案

根据要求,这里是一个正在运行的小提琴与表的创建,数据和选择查询我已经提出了,通过结合以下两个答案。使用所有这些子选项似乎有点低效,但有效

要拯救您,请编辑:并在以下位置进行区分:

编辑:聊天后此解决方案最适合:

SELECT *
FROM (
    SELECT DISTINCT ON (trigger_id, type, name)
        *
    FROM (
         SELECT *
         FROM (
             SELECT
                 *,
                 COUNT(*) OVER (PARTITION BY trigger_id, type, name)
             FROM event
             WHERE user_id = 1
         ) s
    ) t
    ORDER BY trigger_id, type, name, date_created DESC
) u
ORDER BY type ASC, date_created DESC

你可以在下面查询

SELECT * 
FROM (
    SELECT
        a.*,
        COUNT(*) OVER (PARTITION BY trigger_id, type, name) cnt , row_number () over(PARTITION BY trigger_id, type, name order by date_created DESC ) rn
    FROM event a
    WHERE account_id = 'fd80059a-3a16-40fe-9f6b-ad2812875d92'
) s
where rn < = 4 
ORDER BY type ASC, date_created DESC  

谢谢虽然我得到了正确的计数,但我仍然得到了所有记录。不要分组。最后我只想展示4张唱片。基于为每个组创建的日期的最新版本。@Dac0d3r已更新。对于更精确的代码,我真的需要样本代码和预期的输出,请编辑您的问题非常感谢。请看我在文章底部的编辑。我不得不调整一下,但它似乎起作用了。只是速度很慢,即使我的表中只有14条记录。现在请向我们展示您的数据。14记录不应该有这样的影响。也许我的表现不好,表现还不错。我想我有一些网络延迟影响了它。我不得不走了,但我回来后会更新。我会试着做一把小提琴。谢谢!!谢谢没用,但你的行号技巧似乎是每个小组只选择第一条记录的关键。根据你和S-man的回答,我可以在这里用一个有效的SQL组合成一把小提琴,但是对于所有这些嵌套的子选择,它似乎不是最好的实现@Dac0d3r很高兴知道它有帮助。如果您有更好的解决方案,您可以发布并接受相同的解决方案。最后的动机是互相帮助,互相学习。
SELECT *
FROM (
    SELECT DISTINCT ON (trigger_id, type, name)
        *
    FROM (
         SELECT *
         FROM (
             SELECT
                 *,
                 COUNT(*) OVER (PARTITION BY trigger_id, type, name)
             FROM event
             WHERE user_id = 1
         ) s
    ) t
    ORDER BY trigger_id, type, name, date_created DESC
) u
ORDER BY type ASC, date_created DESC
SELECT * 
FROM (
    SELECT
        a.*,
        COUNT(*) OVER (PARTITION BY trigger_id, type, name) cnt , row_number () over(PARTITION BY trigger_id, type, name order by date_created DESC ) rn
    FROM event a
    WHERE account_id = 'fd80059a-3a16-40fe-9f6b-ad2812875d92'
) s
where rn < = 4 
ORDER BY type ASC, date_created DESC