查看表格:
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(),
);
我想
1)首先按“类型” ASC排序,然后按“ date_created” DESC排序
这部分很容易像这样
SELECT *
FROM event
WHERE user_id = 'fd80059a-3a16-40fe-9f6b-ad2812875d92'
ORDER BY type ASC, date_created DESC
2)按“ trigger_id”,“ type”和“ name”分组,并为每个分组计数。是的,如果“ trigger_id”,“ type”和“ name”相同,我想组成一个小组,并显示最近的一个小组,并对该小组中的所有事件进行计数(基本上是事件发生了多少次,因为如果这三个相同,则可以认为该事件是相关的。
这是具有挑战性的部分。理想的情况是这样的:
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
将只给我每组中的第一条记录(因为它们已经按日期排序了),但是所有的列(而不只是GROUP BY子句中的列)加上最后的组计数列。
我现在使用选项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查询。所有这些子选择似乎效率不高,但可以使用。
https://www.db-fiddle.com/f/mNNzwiDbx2iUdgd2vFTRuJ/0
SELECT *
FROM (
SELECT DISTINCT ON (trigger_id, type, name)
*
FROM (
SELECT *,
row_number () over(PARTITION BY trigger_id, type, name order by date_created DESC )
FROM (
SELECT
*,
COUNT(*) OVER (PARTITION BY trigger_id, type, name)
FROM event
WHERE user_id = 1
ORDER BY type ASC, date_created DESC
) s
) t
) u
ORDER BY type ASC, date_created DESC
答案 0 :(得分:1)
Window functions来拯救您(编辑:还有DISTINCT ON
):
SELECT DISTINCT ON (type, date_created)
*
FROM (
SELECT
*,
COUNT(*) OVER (PARTITION BY trigger_id, type, name)
FROM event
WHERE account_id = 'fd80059a-3a16-40fe-9f6b-ad2812875d92'
) s
ORDER BY type ASC, date_created DESC
编辑:聊天后,此解决方案最合适:
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
答案 1 :(得分:0)
您可以检查以下查询
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