根据条件统计连续记录数

Count number of sequential records based on condition

我有一个 table,其中包含最初按时间戳排序的行数:

+----+------------+-----+
| id | date       | foo |
+----+------------+-----+
| 1  | 2017-12-28 | abc |
+----+------------+-----+
| 1  | 2017-12-27 | abc |
+----+------------+-----+
| 2  | 2017-12-27 | xyz |
+----+------------+-----+
| 2  | 2017-12-26 | xyz |
+----+------------+-----+
| 2  | 2017-12-25 | abc |
+----+------------+-----+
| 1  | 2017-12-25 | abc |
+----+------------+-----+
| 2  | 2017-12-25 | abc |
+----+------------+-----+

而且我想获得 连续 条记录的数量 foo 对于不同的 id 像这样:

+----+-----+-------+
| id | foo | count |
+----+-----+-------+
| 1  | abc | 2     |
+----+-----+-------+
| 2  | xyz | 2     |
+----+-----+-------+
| 2  | abc | 1     |
+----+-----+-------+
| 1  | abc | 1     |
+----+-----+-------+
| 2  | abc | 1     |
+----+-----+-------+

因此,here 是带有内置模式的 sqlfiddle。

Window 函数看起来像是解决此类问题的关键,但在我使用的方式中效果不佳。

我很乐意得到任何帮助或至少一些有用的提示。 MySQL 上有一些与此相关的问题,但它们不是很有帮助。

首先,非常感谢您的 sqlfiddle。

使用标准方法 (Tabibitosan) 解决间隙和孤岛问题 row_number()

SQL Fiddle

PostgreSQL 9.6 架构设置:

create table bar (
  id   bigint not null,
  date timestamp without time zone,
  foo  text
);

insert into bar (id, date, foo) values
  (1, '2017-12-28 17:54:02', 'abc'),
  (1, '2017-12-28 17:53:30', 'abc'),
  (2, '2017-12-28 17:50:13', 'xyz'),
  (2, '2017-12-28 17:44:35', 'xyz'),
  (2, '2017-12-28 17:30:00', 'abc'),
  (1, '2017-12-28 17:25:15', 'abc'),
  (2, '2017-12-28 17:21:20', 'abc');

查询 1:

SELECT MAX (id) AS id,
         foo,
         COUNT (*) AS "count"
    FROM (SELECT b.*,
                   ROW_NUMBER () OVER (ORDER BY date DESC)
                 - ROW_NUMBER () OVER (PARTITION BY id ORDER BY date DESC)
                    seq
            FROM bar b) t
GROUP BY foo, seq, id
ORDER BY MAX(DATE) DESC

Results:

| id | foo | count |
|----|-----|-------|
|  1 | abc |     2 |
|  2 | xyz |     2 |
|  2 | abc |     1 |
|  1 | abc |     1 |
|  2 | abc |     1 |