【发布时间】:2018-02-05 18:05:14
【问题描述】:
编辑 2 当您拥有的是按 <SORTING> 排序的表时,要记住的解决方案是 count( <GROUP-START-COND> or null ) over ( order by <SORTING> ) AS groupnr,新的行组由 <GROUP-START-COND> 发出信号,并且您需要一个计数器随着每组行的增加而增加,并且在整个组中保持不变。
原始问题
给定这样的表格:
╔════════╤═══════╤═══════╤════════════════════════════════════...
║ linenr │ level │ key │ value ...
╠════════╪═══════╪═══════╪════════════════════════════════════...
║ 9 │ 1 │ title │ Text processing umbrella: Parse / T...
║ 10 │ 1 │ tags │ text-processing typesetting markdow...
║ 11 │ 1 │ about │ unified is an interface for process...
║ 12 │ 2 │ ... │ and rehype, but it also allows for ...
║ 13 │ 1 │ note │ EXAMPLE ...
║ 16 │ 1 │ tags │ foo bar baz ...
║ 17 │ 1 │ tags │ ctx/tag spaceships/orville ...
...
我如何定义一个window,它允许我在属于同一组的所有values 上使用array_aggregate,其中组定义为具有相邻linenrs 的行,其中第一行具有@ 987654331@ 和 key,以下行有 level = 2 和 key = '...'(仅使用其中一个条件就足够了)。
我正在尝试提出一个涉及over ( ... rows between current row ... ) 的公式,但被卡住了;也许先对组进行编号,然后对组编号进行聚合将是一个很好的解决方案。
编辑我意识到我的问题可能不是最清楚的,缺少一个可行的示例,也许最好将其发布到 dba.stackexchange.com,因此以下是改进后的版本供您参考:
更新问题
我有下表的数据,如下所示; linenrs 单调递增但不一定连续;当key 字段包含省略号... 表示从上面继续的条目时:
create table source (
linenr integer unique not null,
key text not null,
value text );
insert into source values
( 2, 'tags', 'a' ),
( 3, '...', 'b' ),
( 4, 'title', 'The Title' ),
( 5, 'note', 'this is' ),
( 6, '...', 'an EXAMPLE' ),
( 8, 'title', 'over' ),
( 9, '...', 'three' ),
( 10, '...', 'lines' ),
( 11, 'about', 'grouping' );
现在我想要查看根据key 字段的内容分配组号的视图;组号不必是连续的,但对于以... 以外的键开头并贯穿key 为... 的所有行的每组行应该是不同的,如下所示:
╔════════╤═══════╤═══════╤════════════╗
║ linenr │ group │ key │ value ║
╠════════╪═══════╪═══════╪════════════╣
║ 2 │ 1 │ tags │ a ║
║ 3 │ 1 │ ... │ b ║
║ 4 │ 2 │ title │ The Title ║
║ 5 │ 3 │ note │ this is ║
║ 6 │ 3 │ ... │ an EXAMPLE ║
║ 8 │ 4 │ title │ over ║
║ 9 │ 4 │ ... │ three ║
║ 10 │ 4 │ ... │ lines ║
║ 11 │ 5 │ about │ grouping ║
╚════════╧═══════╧═══════╧════════════╝
我尝试使用 windows/partitions 和 tabibitosan 模式来做到这一点,但无法提出任何可行的方法;此外,在lag() 的前一行使用在... 有多个连续行的情况下也无济于事。在电子表格中,这是一件非常容易的事情,但在 SQL 中,我似乎无法引用 current 查询的前一行,可以吗?
解决方案讨论
原来有一个解决方案如此简单,令人痛苦(不是自己想出来的):
select
linenr as linenr,
key as key,
value as value,
sum( rst ) over ( order by linenr ) as group_nr
from ( select
linenr,
key,
value,
case when key != '...' then 1 end as rst
from source ) as x;
这是可行的,因为我们为开始组的行分配了1,否则为null;然后,sum()ming 在所有行上(以正确的顺序)会将nulls 视为零,然后导致所有组起始行获得一个新的group_id,并且所有后续行都保持该计数。如果你知道怎么做就很简单......
积分归用户McNets。
这同样可以在一个简短而令人难忘的单行中完成,参见上面的编辑和下面Erwin Brandstetter 的答案。
EDIT 2 评论者理所当然地抱怨我编辑的问题确实是一个新问题。我认为结果是,在解决顽固问题时,应该尝试找到不会转动的特定螺钉,并提出一个小规模模型,突出该特定部分而忽略其他部分。在这种情况下,聚合具有组号的行对我来说并不是困难的部分,而是分配组号。此外,“定义一个允许我对所有值进行数组聚合的窗口”不是问题的一部分,它是我想象的可能导致解决方案的一部分。
【问题讨论】:
-
您的 Postgres 版本和表定义?假设
linenr被定义为唯一?单行(没有以下级别 2)是否也被视为组? -
这里是 Postgres v10;我想我的编辑回答了你的问题。
-
你用另一个问题替换了问题。
-
@Erwin Brandstetter 我猜你可能会这么说;我意识到包含
level字段和聚合步骤都让人分心,而不是澄清。我会重新编辑我的问题,说这么多。道歉。 -
所以我们可以在已回答的情况下勾选这个?
标签: sql postgresql window-functions gaps-and-islands