我在一个表中有大约 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) 我有一些这样的数字表(状态是免费的或分配的)
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)
,但这就是我得到的:) 我想不出逻辑,如何在 …
我有一个我认为可以使用窗口函数解决的情况,但我不确定。
想象一下下表
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
我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) 我有一个包含以下数据的表,使用 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
.
我很想知道如何创建一个视图,以 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
根据对这个问题的回答,我设法产生了以下输出以获得运行的值总和:
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 上运行)并获得一个与下面非常相似的表。(相反,我想知道我正在尝试的是 …
在这个答案中,Erwin Brandstetter 说:
count(step OR NULL) OVER (ORDER BY date)
是最短的语法,也适用于 Postgres 9.3 或更早版本。count()
只计算非空值。在现代 Postgres 中,更简洁、等效的语法是:Run Code Online (Sandbox Code Playgroud)count(step) FILTER (WHERE step) OVER (ORDER BY date)
我不确定为什么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。
欧文的回答是:
这假设涉及的列是
NOT NULL
. 否则你需要做更多。
所以我更迷茫了。添加count(step OR NULL)
什么来保护我们的查询有什么意义?
任何人都可以分解这一点,也许可以展示两个带有数据的示例,其中只有一个 - 一个 -count(x OR NULL)
有效?