我在Postgres数据库中有一个简单的表log
,看起来像这样(示例简化):
time::timestamptz
action::varchar
time | action
2017-10-16 17:14:49.473903-08 | 'some action'
2017-10-16 17:14:49.473903-08 | 'some other action'
2017-10-17 17:14:49.473903-08 | 'some action'
//etc.
有各种各样的行动。我想查询此表以获得每天一行,其中包含每个操作的计数数组。这是我想要的结果:
day actions
'2017-10-08' | [{"action":"some action", "count":10},
| {"action":"some other action", "count":20}}]
'2017-10-09' | [{"action":"some action", "count":15},
| {"action":"some other action", "count":18}}]
我几乎能够实现这一目标:
SELECT day, json_agg(act) as actions
FROM (
SELECT action, time::date as day, COUNT(*)
FROM log_hits
GROUP BY (action, day)
) act
GROUP BY day
当然,这会导致在actions数组中的每个对象中出现日期......
day actions
'2017-10-08' | [{"action":"some action", day:"2017-10-08", "count":10},
| {"action":"some other action", day:"2017-10-08", "count":20}}]
......这是多余的(可能效率低下)。获取按日分组的结果的正确方法是什么,日期只发生在自己的列中,而操作仅聚合当天?
答案 0 :(得分:5)
使用jsonb_build_object():
WITH log_hits (time, action) AS (
VALUES
('2017-10-16 17:14:49.473903-08'::timestamptz, 'some action'),
('2017-10-16 17:14:49.473903-08', 'some other action'),
('2017-10-17 17:14:49.473903-08', 'some action')
)
SELECT
day,
json_agg(jsonb_build_object('action', action, 'count', count)) as actions
FROM (
SELECT action, time::date as day, COUNT(*)
FROM log_hits
GROUP BY (action, day)
) act
GROUP BY day;
day | actions
------------+--------------------------------------------------------------------------------------
2017-10-17 | [{"count": 1, "action": "some action"}, {"count": 1, "action": "some other action"}]
2017-10-18 | [{"count": 1, "action": "some action"}]
(2 rows)
答案 1 :(得分:1)
您可以先将行转换为jsonb,然后删除day
键
SELECT day, json_agg(row_to_jsonb(act) - 'day') as actions
FROM (
SELECT action, time::date as day, COUNT(*)
FROM log_hits
GROUP BY action, day
) act
GROUP BY day
答案 2 :(得分:1)
不完全是您要求的结果,但无论如何都要张贴,因为有人可能会觉得它更合适:
SELECT day, json_object_agg("action","count") as actions
FROM (
SELECT action, ts::date as day, COUNT(*) as count
FROM log_hits
GROUP BY (action, ts::date) ORDER BY count DESC
) act
GROUP BY day ORDER BY day
| day | actions |
|------------|------------------------------------------------|
| 2017-10-16 | { "some action" : 2, "some other action" : 1 } |
| 2017-10-17 | { "some action" : 1 } |
| 2017-10-18 | { "some action" : 1 } |