微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

根据列值的顺序连接列值

如何解决根据列值的顺序连接列值

我正在尝试找出一种方法,将与联名账户持有人相同的账户组合在一起。一个账户有 1 个主要人,最多有 4 个额外的联名账户持有人。考虑以下示例:

帐号 主要 关节 1 关节2 Joint3 Joint4
123 标记 蒂姆 吉姆 布莱恩 约翰
124 标记 吉姆 蒂姆 布莱恩 约翰
134 吉姆 标记 蒂姆 布莱恩 约翰
324 雪莉 海伦
168 雪莉 海伦

所以在上面:

  • Mark、Tim、Jim、Brian 和 John 都在帐户 123、124、134 上,我希望它们成为一组
  • Ann、Shelly 和 Helen 都在帐户 324 和 168 上,并且将组成另一个

我正在考虑通过使用 case 语句对 Primary 和 Joint%s 进行排序,然后将订单连接成一个字符串,然后我可以对其进行分组来解决这个问题。因此,在 Ann、Shelly 和 Helen 的情况下 - 按字母顺序排列会给我 Ann、Helen 和 Shelly,我会将这些名称连接在一起以获得“AnnHelenShelly”并按此字符串分组。我已经开始这样做了,但是当我遇到一个帐户上有 3 或 4 个联名持有人的情况时,我发现它有点混乱。对于只有一个主要和一个关节的情况,我只是这样做:

num_joints = 1 时的情况,则最少 (primary,joint1) ||最大的(主要的,关节 1) 当 num_joints = 2 时,则最少(主要,关节 1,关节 2)|| (当关节 1 > 最少(主要,关节 1,关节 2)和关节 1 最小(主要,关节 1,关节 2)和关节 2

但我想知道是否有更简单、更具可扩展性的方法来做到这一点,这样当我到达 num_joints = 3 或 4 时,它就不会太混乱。或者,也许还有另一种方法可以对其进行分组,而不必创建由主要持有人和联合持有人按顺序组成的字符串。

其他一些注意事项:

  • 主要条目和联合条目的 ID 都是数字且是唯​​一的 - 因此我可以按此 ID 号订购
  • Joint 条目根据帐户中的关节数量顺序填充 - 即如果帐户中有 3 个关节和一个主要,则主要有一个值,并且关节 1、关节 2 和关节 3 和关节 4 将为空白。

解决方法

使用 UNPIVOT 将列转换为行,然后使用 LISTAGG 按字母顺序聚合每个帐户的名称,然后再次使用 LISTAGG 聚合每个唯一名称列表的帐户。

这个解决方案仍然有点复杂,并没有比您的 CASE 版本简单多少,但它的扩展性很好,并且在解决方案中添加另一列也很简单。该示例使用 LISTAGG,它非常适合显示结果,但如果您要在数据库中处理结果,您的最终生产版本可能不应该使用 LISTAGG

示例架构

create table accounts
(
    account number,primary varchar2(100),joint1 varchar2(100),joint2 varchar2(100),joint3 varchar2(100),joint4 varchar2(100)
);

insert into accounts
select 123,'Mark','Tim','Jim','Brian','John' from dual union all
select 124,'John' from dual union all
select 134,'John' from dual union all
select 324,'Ann','Shelly','Helen','',''     from dual union all
select 168,''     from dual;

查询

--Accounts per group.
select names,listagg(account,',') within group (order by account) accounts
from
(
    --Aggregate names into alphabetical list per account.
    select
        account,listagg(account_name,') within group (order by account_name) names
    from
    (
        --Unpivot columns into rows.
        select account,account_type,account_name
        from accounts
        unpivot (account_name for account_type in
            (primary as 'primary',joint1 as 'join1',joint2 as 'joint2',joint3 as 'joint3',joint4 as 'joint4')
        )
    )
    group by account
)
group by names
order by names;

结果

NAMES                     ACCOUNTS
-----------------------   -----------
Ann,Helen,Shelly          168,324
Brian,Jim,John,Mark,Tim   123,124,134

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。