Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/81.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
sql中的连续时间间隔分组_Sql_Postgresql_Gaps And Islands - Fatal编程技术网

sql中的连续时间间隔分组

sql中的连续时间间隔分组,sql,postgresql,gaps-and-islands,Sql,Postgresql,Gaps And Islands,假设数据结构的类型为 stock_name, action, start_date, end_date google, growing, 1, 2 google, growing, 2, 3 google, falling, 3, 4 google, growing, 4, 5 yahoo, growing, 1, 2 如何将其聚合以合并连续的时间间隔 输出如下所示: stock_name, action, start_date, end_date google, growing, 1, 3

假设数据结构的类型为

stock_name, action, start_date, end_date
google, growing, 1, 2
google, growing, 2, 3
google, falling, 3, 4
google, growing, 4, 5
yahoo, growing, 1, 2
如何将其聚合以合并连续的时间间隔

输出如下所示:

stock_name, action, start_date, end_date
google, growing, 1, 3
google, falling, 3, 4
google, growing, 4, 5
yahoo, growing, 1, 2
我曾想过使用rank window函数以常量对连续数据进行编号,然后按常量和action/name进行分组,但我无法完全实现,如下所示:

stock_name, action, start_date, end_date, rank
google, growing, 1, 2, 1
google, growing, 2, 3, 1
google, falling, 3, 4, 1
google, growing, 4, 5, 2
yahoo, growing, 1, 2, 1
如果这是Mysql,我会很容易用变量来解决它,但这在postgres中是不可能的

可以有任意数量的连续间隔,因此不能选择自加入预定的nr次


解决方案的优雅性(性能、可读性)很重要。

您可以在PL/pgSQL中很好地使用变量

我会用一个表函数来解决这个问题

假设该表名为
stock
,我的代码如下所示:

CREATE OR REPLACE FUNCTION combine_periods() RETURNS SETOF stock
   LANGUAGE plpgsql STABLE AS
$$DECLARE
   s stock;
   period stock;
BEGIN
   FOR s IN
      SELECT stock_name, action, start_date, end_date
      FROM stock
      ORDER BY stock_name, action, start_date
   LOOP
      /* is this a new period? */
      IF period IS NOT NULL AND
         (period.stock_name <> s.stock_name
            OR period.action <> s.action
            OR period.end_date <> s.start_date)
      THEN
         /* new period, output last period */
         RETURN NEXT period;
         period := NULL;
      ELSE
         IF period IS NOT NULL
         THEN
            /* period continues, update end_date */
            period.end_date := s.end_date;
         END IF;
      END IF;

      /* remember the beginning of a new period */
      IF period IS NULL
      THEN
         period := s;
      END IF;
   END LOOP;

   /* output the last period */
   IF period IS NOT NULL
   THEN
      RETURN NEXT period;
   END IF;

   RETURN;
END;$$;
test=> SELECT * FROM combine_periods();
┌────────────┬─────────┬────────────┬──────────┐
│ stock_name │ action  │ start_date │ end_date │
├────────────┼─────────┼────────────┼──────────┤
│ google     │ falling │          3 │        4 │
│ google     │ growing │          1 │        3 │
│ google     │ growing │          4 │        5 │
│ yahoo      │ growing │          1 │        2 │
└────────────┴─────────┴────────────┴──────────┘
(4 rows)

连续的时间间隔是否可以包含2条以上的记录(例如3、4、5)?这在我看来实际上像是一个缺口和孤岛问题。@AdrianBR
如果这是Mysql,我可以用变量轻松解决它,但这在postgres中是不可能的
-什么在postgres中是不可能的?@AdrianBR使用postgres过程语言,如果需要用户定义的变量,通常使用窗口函数来解决。这似乎很接近:或者这个:或者这个: