SQL 将行分组为对

Posted

技术标签:

【中文标题】SQL 将行分组为对【英文标题】:SQL group rows into pairs 【发布时间】:2018-05-10 16:34:04 【问题描述】:

我正在尝试将某种唯一标识符 (uid) 添加到由成对行组成的分区中,即在大小 = 2 行的窗口分区中为 (identifier1,identifier2) 的每两行生成一些 uid/tag .

因此,例如,ID X 的前 2 行将获得 uid A,相同 ID 的接下来两行将获得 uid B,如果在 ID X 的分区中只剩下一行,它会得到 id C。

这是我想要完成的,图片说明了表的结构,我手动添加了预期标识符来说明目标:

这是我目前的SQL,ntile没有解决,因为分区大小不同:

select
rowId
, ntile(2) over (partition by firstIdentifier, secondIdentifier order by timestamp asc) as ntile
, *
from log;

已经尝试过 ntile((count(*) over partition...) / 2),但这不起作用。

可以使用 md5() 或类似方法生成 UID,但我无法如上所示标记行(因此我可以 md5 生成的标记/uid)

【问题讨论】:

【参考方案1】:

虽然 Snowflake 窗口函数不支持 count(*),但支持 count(1) 并可用于创建唯一标识符。下面是一个整数唯一 ID 匹配行对并处理“奇数”行组的示例:

select 
ntile(2) over (partition by firstIdentifier, secondIdentifier order by timestamp asc) as ntile
,ceil(count(1) over( partition by firstIdentifier, secondIdentifier order by timestamp asc) / 2) as id
, *
from log;

【讨论】:

几乎解决了,但是高亮的行应该设置为1而不是2:imgur.com/a/MGv7yrC 我无法重现该问题:即使时间戳与您的屏幕截图中的相同,我仍会继续获得该数据的 1、2、3 对。你能发布你用来生成结果的完整 SQL 吗?【参考方案2】:
select *, char(65 + (row_number() over(partition by 
firstidentifier,secondidentifier order by timestamp)-1)/2) 
expectedidentifier from log 
order by firstidentifier, timestamp

这是 Sql Server 版本

with log (firstidentifier,secondidentifier, timestamp)
as (
select 15396, 14460, 1 union all
select 15396, 14460, 1 union all
select 19744, 14451, 1 union all
select 19744, 14451, 1 union all
select 19744, 14451, 1 union all
select 15590, 12404, 1 union all
select 15590, 12404, 1 union all
select 15590, 12404, 1 union all
select 15590, 12404, 1 union all
select 15590, 12404, 1 
)
select *, char(65 + (row_number() over(partition by 
firstidentifier,secondidentifier order by timestamp)-1)/2) 
expectedidentifier from log 
order by firstidentifier,secondidentifier,timestamp

【讨论】:

谢谢,但这并没有输出预期的结果 对不起,我错过了时间戳相同的情况。用 row_number 更新了查询。现在应该可以工作了。

以上是关于SQL 将行分组为对的主要内容,如果未能解决你的问题,请参考以下文章

按累积时间间隔将行分组

使用 dplyr 将行添加到分组数据?

Tsql 将行转置为列,按列分组

分组后将行值显示为列-Oracle

将行分组到一个新的 Pandas DataFrame 中,每组一行

Crystal Report,根据Criteria将行分组为单行