SQL 将行数据分组为一行
SQL Group up rows data into one row
我在 table 中有这样的数据:
我想组织 table 数据,以便每行最多可以有 3 个字母,按帐号分组。
下面是我想要的结果:
我可以使用密集排名对帐号进行分组,但不确定如何以上述格式获取我想要的数据。
逻辑:
帐户 123 有 4 个字母。最终结果按帐号前 3 个字母分组,因为每行最多只能有 3 个字母。第四个字母必须在第二行。
这是一个使用 conditional aggregation
的选项,首先创建一个 row_number
,然后使用 %
(取模运算符)每 3 行创建一个行分组:
select account_number,
max(case when rn % 3 = 1 then letter end) as letter1,
max(case when rn % 3 = 2 then letter end) as letter2,
max(case when rn % 3 = 0 then letter end) as letter3
from (
select *, row_number() over (partition by account_number, rn % 3 order by rn) newrn
from (
select *, row_number() over (partition by account_number order by letter) rn
from yourtable
) t
) y
group by account_number, newrn
order by account_number
我只需要调用一次 row_number()
:
select account_number,
max(case when seqnum % 3 = 1 then letter end) as letter_a,
max(case when seqnum % 3 = 2 then letter end) as letter_b,
max(case when seqnum % 3 = 0 then letter end) as letter_c
from (select t.*,
row_number() over (partition by account_number order by letter) as seqnum
from t
) t
group by account_number, floor( (seqnum - 1) / 3)
order by account_number, min(seqnum);
我在 table 中有这样的数据:
我想组织 table 数据,以便每行最多可以有 3 个字母,按帐号分组。
下面是我想要的结果:
我可以使用密集排名对帐号进行分组,但不确定如何以上述格式获取我想要的数据。
逻辑: 帐户 123 有 4 个字母。最终结果按帐号前 3 个字母分组,因为每行最多只能有 3 个字母。第四个字母必须在第二行。
这是一个使用 conditional aggregation
的选项,首先创建一个 row_number
,然后使用 %
(取模运算符)每 3 行创建一个行分组:
select account_number,
max(case when rn % 3 = 1 then letter end) as letter1,
max(case when rn % 3 = 2 then letter end) as letter2,
max(case when rn % 3 = 0 then letter end) as letter3
from (
select *, row_number() over (partition by account_number, rn % 3 order by rn) newrn
from (
select *, row_number() over (partition by account_number order by letter) rn
from yourtable
) t
) y
group by account_number, newrn
order by account_number
我只需要调用一次 row_number()
:
select account_number,
max(case when seqnum % 3 = 1 then letter end) as letter_a,
max(case when seqnum % 3 = 2 then letter end) as letter_b,
max(case when seqnum % 3 = 0 then letter end) as letter_c
from (select t.*,
row_number() over (partition by account_number order by letter) as seqnum
from t
) t
group by account_number, floor( (seqnum - 1) / 3)
order by account_number, min(seqnum);