如何在 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
列是否是brothers
或sisters
的子串,然后使用LISTAGG
聚合匹配名字。
假设您希望 name
与 id
在 brothers
或 sisters
列表中的顺序相同,那么您可以使用:
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
但是,如果您希望 name
按 id
值排序,那么您可以使用:
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
我有一个像下面这样的 table,它有名称和 ID。
ID | 姓名 |
---|---|
1 | 罗柏 |
2 | 珊莎 |
3 | 艾莉亚 |
4 | 麸皮 |
5 | 瑞肯 |
6 | 瑟曦 |
7 | 海梅 |
8 | 提利昂 |
还有一个 table 如下所示
姓氏 | 兄弟 | 姐妹们 |
---|---|---|
斯塔克 | 1,4,5 | 2,3 |
伦尼斯特 | 7,8 | 6 |
我需要一个查询,它会在一行中给出 stark 家族兄弟的名字,并用逗号分隔
姓氏 | 兄弟 | 姐妹们 |
---|---|---|
斯塔克 | 罗柏、布兰、瑞肯 | 珊莎,艾莉亚 |
感谢您的帮助
可以使用相关子查询,检查id
列是否是brothers
或sisters
的子串,然后使用LISTAGG
聚合匹配名字。
假设您希望 name
与 id
在 brothers
或 sisters
列表中的顺序相同,那么您可以使用:
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
但是,如果您希望 name
按 id
值排序,那么您可以使用:
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