postgres中的GROUP BY列和子句

时间:2016-04-21 10:06:21

标签: 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_id分组。每当我有一个标志NEW_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

但我不知道如何正确地表达群体。有什么想法吗?

1 个答案:

答案 0 :(得分:2)

更新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
);

原始回答

据我了解,您正在尝试按会话ID分组事件 &#34;它是否是NEW_SESSION&#34;旗。如果是这样,那么我将其表达如下:

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;