如何在 oracle 中用逗号数据中的名称交换 id

How can I exchange ids with names in comma data in oracle

我有一个像下面这样的 table,它有名称和 ID。

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

还有一个 table 如下所示

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

我需要一个查询,它会在一行中给出 stark 家族兄弟的名字,并用逗号分隔

姓氏 兄弟 姐妹们
斯塔克 罗柏、布兰、瑞肯 珊莎,艾莉亚

感谢您的帮助

可以使用相关子查询,检查id列是否是brotherssisters的子串,然后使用LISTAGG聚合匹配名字。

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

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;

两者输出:

FAMILY_NAME BROTHERS SISTERS
Stark Robb,Bran,Rickon Sansa,Arya
Lannister Jaime,Tyrion Cersei

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

WHERE  family_name = 'Stark'

db<>fiddle here