2016-08-25 28 views
-1

我有两个表ORACLE连接两个表逗号分隔IDS

表1

ID  NAME 
1  Person1 
2  Person2 
3  Person3 

表2

ID  GROUP_ID 
1  1 
2  2,3 

在上述所有列的编号是指相同的ID(示例 - a部门)

我期望的输出(通过加入两个表)

GROUP_ID  NAME 
1   Person1 
2,3   Person2,Person3 

有没有一个查询,我可以做到这一点。

+6

您不应该存储逗号分隔值。修复你的数据模型,事情变得更容易 –

+2

这会变得很难看 - 你必须首先拆分表2,使其有3行,做连接,再次合并行。它可以完成 - 但是,真的,你想吗? – Hogan

回答

0
select t2.group_id, listagg(t1.name,',') WITHIN GROUP (ORDER BY 1) 
    from table2 t2, table1 t1 
where ','||t2.group_id||',' like '%,'||t1.id||',%' 
group by t2.id, t2.group_id 

正常化您的数据模型,这种变态!数据库中不应该存在数据库分隔列表。每个数据单元只有单独的行。

+0

感谢它的作品 – deskatur

+0

这可以起作用,除非名称的顺序必须与逗号分隔字符串中ID的顺序相匹配。 – mathguy

+0

我怎么能从我的表中添加额外的字段到这个查询1 – deskatur

1

可以这样做。你不应该这样做,但也许你没有能力改变世界。 (如果你有发言权,你应该规范你的表格设计 - 在你的情况下,输入和输出都不符合第一范式)。

回答更多是我自己的好习惯......这个解决方案保证名称将按照与ID相同的顺序列出。它不是最有效的,它不处理在第一个表中找不到的id(它只是放弃它们而不是留下某种标记)。

with 
    table_1 (id, name) as (
     select 1, 'Person1' from dual union all 
     select 2, 'Person2' from dual union all 
     select 3, 'Person3' from dual 
    ), 
    table_2 (id, group_id) as (
     select 1, '1' from dual union all 
     select 2, '2,3' from dual 
    ), 
    prep (id, lvl, token) as (
     select id, level, regexp_substr(group_id, '[^,]', 1, level) 
     from table_2 
     connect by level <= regexp_count(group_id, ',') + 1 
       and prior id = id 
       and prior sys_guid() is not null 
    ) 
select p.id, listagg(t1.name, ',') within group (order by p.lvl) as group_names 
from table_1 t1 inner join prep p on t1.id = p.token 
group by p.id; 

    ID GROUP_NAMES 
---- -------------------- 
    1 Person1 
    2 Person2,Person3