首页 > 解决方案 > 如何在 oracle 中用逗号数据中的名称交换 id

问题描述

我有一个像下面这样的表,其中包含名称和 ID。

ID 姓名
1 罗布
2 珊莎
3 艾莉亚
4
5 瑞肯
6 瑟曦
7 海梅
8 提利昂

还有一个如下表

兄弟 姐妹
斯塔克 1,4,5 2,3
伦尼斯特 7,8 6

我需要一个查询,它将在一行中给出兄弟的名字,以逗号分隔

兄弟 姐妹
斯塔克 罗伯、布兰、瑞肯 珊莎,艾莉亚

谢谢你的帮助

标签: sqloraclelistagg

解决方案


您可以使用相关子查询并检查该id列是否是brothersor的子字符串,sisters然后用于LISTAGG聚合匹配的名称。

假设您希望 与or列表中name的顺序相同,那么您可以使用:idbrotherssisters

SELECT family_name,
       (
          SELECT LISTAGG(b.name, ',')
                   WITHIN GROUP (
                     ORDER BY INSTR(','||f.brothers||',', ','||b.id||',')
                   )
          FROM   people b
          WHERE  INSTR(','||f.brothers||',', ','||b.id||',') > 0
       ) AS brothers,
       (
          SELECT LISTAGG(s.name, ',')
                   WITHIN GROUP (
                     ORDER BY INSTR(','||f.sisters||',', ','||s.id||',')
                   )
          FROM   people s
          WHERE  INSTR(','||f.sisters||',', ','||s.id||',') > 0
       ) AS sisters
FROM   families f

但是,如果您希望nameid值排序,则可以使用:

SELECT family_name,
       (
          SELECT LISTAGG(b.name, ',') WITHIN GROUP (ORDER BY b.id)
          FROM   people b
          WHERE  ','||f.brothers||',' LIKE '%,'||b.id||',%'
       ) AS brothers,
       (
          SELECT LISTAGG(s.name, ',') WITHIN GROUP (ORDER BY s.id)
          FROM   people s
          WHERE  ','||f.sisters||',' LIKE '%,'||s.id||',%'
       ) AS sisters
FROM   families f

其中,对于您的示例数据:

CREATE TABLE people (ID, Name) AS
SELECT 1, 'Robb' FROM DUAL UNION ALL
SELECT 2, 'Sansa' FROM DUAL UNION ALL
SELECT 3, 'Arya' FROM DUAL UNION ALL
SELECT 4, 'Bran' FROM DUAL UNION ALL
SELECT 5, 'Rickon' FROM DUAL UNION ALL
SELECT 6, 'Cersei' FROM DUAL UNION ALL
SELECT 7, 'Jaime' FROM DUAL UNION ALL
SELECT 8, 'Tyrion' FROM DUAL;

CREATE TABLE families (Family_Name, brothers, sisters ) AS
SELECT 'Stark', '1,4,5', '2,3' FROM DUAL UNION ALL
SELECT 'Lannister', '7,8', '6' FROM DUAL;

两个输出:

兄弟 姐妹
斯塔克 罗伯、布兰、瑞肯 珊莎,艾莉亚
兰尼斯特 詹姆,提利昂 瑟曦

如果您只想要该Stark行,则将过滤条件添加为任一查询的最后一行:

WHERE  family_name = 'Stark'

db<>在这里摆弄


推荐阅读