相关疑难解决方法(0)

在 Postgresql 查询中有效地选择多个连续范围的开始和结束

我在一个表中有大约 10 亿行数据,其中有一个名称和一个 1-288 范围内的整数。对于给定的name,每个int都是唯一的,并且并非该范围内的每个可能的整数都存在——因此存在间隙。

此查询生成一个示例案例:

--what I have:
SELECT *
FROM ( VALUES ('foo', 2),
              ('foo', 3),
              ('foo', 4),
              ('foo', 10),
              ('foo', 11),
              ('foo', 13),
              ('bar', 1),
              ('bar', 2),
              ('bar', 3)
     ) AS baz ("name", "int")
Run Code Online (Sandbox Code Playgroud)

我想为每个名称和连续整数序列生成一个查找表。每个这样的行将包含:

name -- name列的值
start -- 连续序列中的第一个整数
end --连续序列中的最后一个值
span -- end - start + 1

此查询为上述示例生成示例输出:

--what I need:
SELECT * 
FROM ( VALUES ('foo', 2, 4, 3),
              ('foo', 10, 11, 2),
              ('foo', 13, 13, 1),
              ('bar', …
Run Code Online (Sandbox Code Playgroud)

postgresql query

20
推荐指数
3
解决办法
1万
查看次数

从表中查找“n”个连续的空闲数字

我有一些这样的数字表(状态是免费的或分配的)

id_set 号码状态         
-----------------------
1 000001 已分配
1 000002 免费
1 000003 已分配
1 000004 免费
1 000005 免费
1 000006 已分配
1 000007 已分配
1 000008 免费
1 000009 免费
1 000010 免费
1 000011 已分配
1 000012 已分配
1 000013 已分配
1 000014 免费
1 000015 已分配

我需要找到“n”个连续数字,因此对于 n = 3,查询将返回

1 000008 免费
1 000009 免费
1 000010 免费

它应该只返回每个 id_set 的第一个可能的组(实际上,它只会为每个查询的 id_set 执行)

我正在检查 WINDOW 函数,尝试了一些类似的查询COUNT(id_number) OVER (PARTITION BY id_set ROWS UNBOUNDED PRECEDING),但这就是我得到的:) 我想不出逻辑,如何在 …

postgresql window-functions group-by gaps-and-islands

19
推荐指数
4
解决办法
3万
查看次数

分组或窗口

我有一个我认为可以使用窗口函数解决的情况,但我不确定。

想象一下下表

CREATE TABLE tmp
  ( date timestamp,        
    id_type integer
  ) ;

INSERT INTO tmp 
    ( date, id_type )
VALUES
    ( '2017-01-10 07:19:21.0', 3 ),
    ( '2017-01-10 07:19:22.0', 3 ),
    ( '2017-01-10 07:19:23.1', 3 ),
    ( '2017-01-10 07:19:24.1', 3 ),
    ( '2017-01-10 07:19:25.0', 3 ),
    ( '2017-01-10 07:19:26.0', 5 ),
    ( '2017-01-10 07:19:27.1', 3 ),
    ( '2017-01-10 07:19:28.0', 5 ),
    ( '2017-01-10 07:19:29.0', 5 ),
    ( '2017-01-10 07:19:30.1', 3 ),
    ( '2017-01-10 07:19:31.0', 5 ),
    ( '2017-01-10 07:19:32.0', 3 ), …
Run Code Online (Sandbox Code Playgroud)

postgresql window-functions group-by gaps-and-islands postgresql-8.4

13
推荐指数
6
解决办法
1867
查看次数

PostgreSQL:为表中的每个组生成一系列日期

balances在 PostgreSQL 9.3 中有一个表,如下所示:

CREATE TABLE balances (
  user_id INT
, balance INT
, as_of_date DATE
);

INSERT INTO balances (user_id, balance, as_of_date) VALUES
  (1, 100, '2016-01-03')
, (1,  50, '2016-01-02')
, (1,  10, '2016-01-01')
, (2, 200, '2016-01-01')
, (3,  30, '2016-01-03');
Run Code Online (Sandbox Code Playgroud)

它只包含用户进行交易的日期的余额。我需要它为每个用户包含一行以及给定日期范围内每个日期的余额。

  • 如果用户在范围内的给定日期没有行,我需要使用他们前一天的余额。
  • 如果用户在范围内的给定日期之后创建了他们的帐户,我需要避免为该用户/日期组合创建一行。

我可以引用一个accounts表来获取用户的create_date

CREATE TABLE accounts (
  user_id INT
, create_date DATE
);

INSERT INTO accounts (user_id, create_date) VALUES
  (1, '2015-12-01')
, (2, '2015-12-31')
, (3, '2016-01-03');
Run Code Online (Sandbox Code Playgroud)

我想要的结果是这样的:

+---------+---------+--------------------------+
| …
Run Code Online (Sandbox Code Playgroud)

postgresql group-by

9
推荐指数
1
解决办法
1万
查看次数

GROUP BY 可能的序列

我有一个包含以下数据的表,使用 Postgres 9.6:

log_id | 序列 | made_at(时间戳)
206480 1 1
206480 1 2
206480 2 3
206480 3 4
206480 1 5
206480 2 6
206480 4 7
206480 5 8
206480 1 9
206480 2 10
206481 1 11
206481 2 12
206481 3 13
206481 4 14

我必须对 ID 进行分组和聚合,以便获得一系列可能的序列。最后,我希望数据看起来像这样:

log_id | 序列
206480 {1,1,2,3}
206480 {1,2,4,5}
206480{1,2}
206481 {1,2,3,4}

在以下情况下,我想要一个新行(带有序列):

  • log_id变化; 或者
  • 下一个序列号低于当前序列号。

还有另一列指定排序(时间戳),但它在另一个表中(我加入它们并使用该时间戳)。为了使事情更容易,我省略了它,但我们可以假设该列名为made_at.

postgresql gaps-and-islands

6
推荐指数
1
解决办法
839
查看次数

如何获得分组时间戳的最小值和最大值

我很想知道如何创建一个视图,以 10 分钟最接近 10 分钟的间隔分组时间戳,并包含每个最小和最大时间戳。

所以一个看起来像这样的表:

| Hero         | timestamp           |

| Batman       | 2016-12-08 12:00:00 |
| Batman       | 2016-12-08 12:07:00 |
| Batman       | 2016-12-08 13:00:00 |
| Batman       | 2016-12-08 14:00:00 |
| Wonder Woman | 2016-12-08 10:15:00 |
| Wonder Woman | 2016-12-08 10:18:00 |
| Wonder Woman | 2016-12-08 10:25:00 |
| Wonder Woman | 2016-12-08 10:30:00 |
Run Code Online (Sandbox Code Playgroud)

会导致这样的观点

| Hero         | start_time          | end_time            |

| Batman       | 2016-12-08 12:00:00 | 2016-12-08 12:07:00 | …
Run Code Online (Sandbox Code Playgroud)

postgresql group-by gaps-and-islands datetime postgresql-9.5

6
推荐指数
1
解决办法
2万
查看次数

特殊累积和基于前一行的行数据转换

根据对这个问题回答,我设法产生了以下输出以获得运行的值总和:

id      creation                    operation       value       running sum
SyJw-c  2016-09-01 00:11:08.307419  positive_op_1   1.33        28.82
SyJw-c  2016-08-21 08:32:54.431662  negative_op_1   -1          27.49
SyJw-c  2016-08-18 07:38:33.878365  positive_op_2   1           28.49
SyJw-c  2016-08-14 18:12:03.599797  negative_op_1   -1          27.49
SyJw-c  2016-08-02 15:44:29.693303  positive_op_1   1.33        28.49
SyJw-c  2016-07-31 12:08:50.659905  override_op_1   4.66        27.16
SyJw-c  2016-06-26 06:53:54.537603  negative_op_1   -3.5        22.5
SyJw-c  2016-05-31 13:34:08.005687  negative_op_1   -1          26
SyJw-c  2016-05-31 13:34:04.776970  negative_op_1   -1          27
SyJw-c  2016-05-31 11:27:09.502983  override_op_2   28          28
Run Code Online (Sandbox Code Playgroud)

我的情况更复杂。我不仅需要对这些值求和,还需要能够首先根据其下方行的运行总和对某些行执行转换。

我先解释一下动机:

目前我有一个带有增量、减量和覆盖操作的表。我想将数据移植到一个只有增量和减量操作的表中,这样我就可以直接总结这些值。我不希望维护旧表,只是一种将数据迁移到更简单模型的方法,因此只将数据附加到新表。

采用上面的“原始”表,我想编写一个查询(我在 postgresql 9.5 上运行)并获得一个与下面非常相似的表。(相反,我想知道我正在尝试的是 …

postgresql migration window-functions

5
推荐指数
1
解决办法
213
查看次数

在什么情况下,间隙和岛屿需要计数(x 或空)?

这个答案中,Erwin Brandstetter 说:

count(step OR NULL) OVER (ORDER BY date)是最短的语法,也适用于 Postgres 9.3 或更早版本。count()只计算非空值。在现代 Postgres 中,更简洁、等效的语法是:

count(step) FILTER (WHERE step) OVER (ORDER BY date)
Run Code Online (Sandbox Code Playgroud)

我不确定为什么count(step OR NULL)是首选。在我的查询中,我执行以下操作。我重命名了我的变量以匹配他的同时保持语法。

CASE WHEN lag(id_type) OVER (ORDER BY date) <> id_type THEN 1 END AS step
Run Code Online (Sandbox Code Playgroud)

我们正在计算它返回的值。请注意,case 只能返回 1 或 null。

  • 如果两者不相等,则返回 1。
  • 如果它们相等,则返回不计算在内的 null。

欧文的回答是:

这假设涉及的列是NOT NULL. 否则你需要做更多。

所以我更迷茫了。添加count(step OR NULL)什么来保护我们的查询有什么意义?

任何人都可以分解这一点,也许可以展示两个带有数据的示例,其中只有一个 - 一个 -count(x OR NULL)有效?

postgresql null count window-functions gaps-and-islands

2
推荐指数
2
解决办法
842
查看次数