postgresql - postgres 中的 GROUP BY 列和子句

标签 postgresql group-by amazon-redshift window-functions gaps-and-islands

我想按列值以及满足另一个条件时对表的列进行分组。例如,如下表:

事件:

id  session_id  flags        created_at  ...
--------------------------------------------
1   100         OTHER        ...
2   101         OTHER        ...
3   101         NEW_SESSION  ...
4   101         OTHER        ...
5   101         NEW_SESSION  ...  
6   100         OTHER        ...
7   102         OTHER        ...

我想要以下结果:

session_id  events_count first_event_id  last_event_id  
-------------------------------------------------------
100-0       2            1               6
101-0       1            2               2
101-1       2            3               4
101-2       1            5               5
102-0       1            7               7

基本思想是我想从事件中提取 session 。它们按 session_id 分组。每当我有 NEW_SESSION 标志时,我也想要一个新 session 。

查询是这样的:

SELECT ? as session_id
  , count(id) as events_count
  , MIN(id) as first_event_id
  , MAX(id) last_event_id
GROUP BY session_id
  -- , and whenever flags is NEW_SESSION
ORDER BY id

但我不知道如何正确表达按条件分组。有什么想法吗?

最佳答案

更新2

在评论中我注意到您希望它们独一无二。然后我们可以使用一个变量:

SET @inc := 0;

(
  SELECT CONCAT(session_id, '-', !ABS(STRCMP(flags, 'NEW_SESSION'))) AS session_id
  , COUNT(id) AS events_count
  , MIN(id) AS first_event_id
  , MAX(id) last_event_id
  FROM events
  WHERE flags != 'NEW_SESSION'
  GROUP BY events.session_id, events.flags
  ORDER BY events.id
) UNION (
  SELECT CONCAT(session_id, '-', @inc := @inc + 1) AS session_id
  , COUNT(id) AS events_count
  , MIN(id) AS first_event_id
  , MAX(id) last_event_id
  FROM events
  WHERE flags = 'NEW_SESSION'
  GROUP by events.id
  ORDER BY events.id
);

更新

以下内容会阻止对 NEW_SESSION 行进行分组:

(
  SELECT CONCAT(session_id, '-', !ABS(STRCMP(flags, 'NEW_SESSION'))) AS session_id
  , COUNT(id) AS events_count
  , MIN(id) AS first_event_id
  , MAX(id) last_event_id
  FROM events
  WHERE flags != 'NEW_SESSION'
  GROUP BY events.session_id, events.flags
  ORDER BY events.id
) UNION (
  SELECT CONCAT(session_id, '-1') AS session_id
  , COUNT(id) AS events_count
  , MIN(id) AS first_event_id
  , MAX(id) last_event_id
  FROM events
  WHERE flags = 'NEW_SESSION'
  GROUP BY id
  ORDER BY events.id
);

原始答案

据我了解,您正在尝试按 session ID 对事件进行分组,并且 “是否是 NEW_SESSION”标志。如果是这样,那么我会这样表达:

SELECT CONCAT(session_id, '-', !ABS(STRCMP(flags, 'NEW_SESSION'))) AS session_id
, COUNT(id) AS events_count
, MIN(id) AS first_event_id
, MAX(id) last_event_id
FROM events
GROUP BY events.session_id, events.flags
ORDER BY events.id;

关于postgresql - postgres 中的 GROUP BY 列和子句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36766317/

相关文章:

sql - Postgres 中的模糊分组

c# - GroupBy 无法翻译

sql - Postgres/Redshift : Extract Quarter and Year from date column for a group by in one call?

sql - 带 Redshift 的 MODE 聚合函数

ruby-on-rails - Rails 5 - 如何将外键迁移到 PostgreSQL?

postgresql - 用 puppet 修改 postgresql 模板

sql - 返回对应值变化的账户的所有历史账户记录

sql - postgres 按整数类型列分组比字符类型列更快?

PostgreSQL 函数 gen_random_uuid() 不工作

import - 使用 COPY 导入时 Redshift 添加列