Oracle SQL-字段中每个串联列表ID的返回值

Oracle SQL-字段中每个串联列表ID的返回值,sql,oracle,Sql,Oracle,我正在使用Oracle 11g数据库。我有一个项目表,其中包括一个表示项目关联产品的字段。products字段中的数据可能包含也可能不包含由逗号分隔的串联值列表,其中每个值对应于包含产品名称的备用查找表中的产品ID。如果“产品”字段中至少存在一个产品值,则该字段将以逗号开头和结尾 ITEM TABLE ╔══════╦═══════════════════╗ ║ ITEM ║ PRODUCTS ║ ╠══════╬═══════════════════╣ ║ 12 ║ ,1

我正在使用Oracle 11g数据库。我有一个项目表,其中包括一个表示项目关联产品的字段。products字段中的数据可能包含也可能不包含由逗号分隔的串联值列表,其中每个值对应于包含产品名称的备用查找表中的产品ID。如果“产品”字段中至少存在一个产品值,则该字段将以逗号开头和结尾

ITEM TABLE ╔══════╦═══════════════════╗ ║ ITEM ║ PRODUCTS ║ ╠══════╬═══════════════════╣ ║ 12 ║ ,101,102,103, ║ ║ 34 ║ ,103,105, ║ ║ 56 ║ ,101,102,104,105, ║ ║ 78 ║ ║ ║ 90 ║ ,102, ║ ╚══════╩═══════════════════╝ PRODUCTS TABLE ╔════════════╦══════╗ ║ PRODUCT_ID ║ NAME ║ ╠════════════╬══════╣ ║ 101 ║ PA ║ ║ 102 ║ PB ║ ║ 103 ║ PC ║ ║ 104 ║ PD ║ ║ 105 ║ PE ║ ╚════════════╩══════╝ 项目表 ╔══════╦═══════════════════╗ ║ 项目║ 产品║ ╠══════╬═══════════════════╣ ║ 12║ ,101,102,103, ║ ║ 34║ ,103,105, ║ ║ 56║ ,101,102,104,105, ║ ║ 78║ ║ ║ 90║ ,102, ║ ╚══════╩═══════════════════╝ 产品表 ╔════════════╦══════╗ ║ 产品标识║ 名称║ ╠════════════╬══════╣ ║ 101║ 帕║ ║ 102║ PB║ ║ 103║ 个人计算机║ ║ 104║ PD║ ║ 105║ 体育课║ ╚════════════╩══════╝ 我的目标是执行一个SELECT查询,以通过垂直条获得一个项目列表及其连接的产品名称,但我不确定如何到达该列表

DESIRED RESULT ╔══════╦═════════════╗ ║ ITEM ║ PRODUCTS ║ ╠══════╬═════════════╣ ║ 12 ║ PA|PB|PC ║ ║ 34 ║ PC|PE ║ ║ 56 ║ PA|PB|PD|PE ║ ║ 78 ║ ║ ║ 90 ║ PB ║ ╚══════╩═════════════╝ 期望结果 ╔══════╦═════════════╗ ║ 项目║ 产品║ ╠══════╬═════════════╣ ║ 12║ PA | PB | PC║ ║ 34║ PC | PE║ ║ 56║ PA | PB | PD | PE║ ║ 78║ ║ ║ 90║ PB║ ╚══════╩═════════════╝
非常感谢您的帮助或指导。

逗号分隔值不是存储数据的正确方法。考虑规范模式。< /P> 您可以做的是首先使用分层的
connectby
将逗号分隔的列表转换为单独的行,然后将结果与products表连接,最后使用listagg将产品名称聚合回
分隔的值

select i.item,
    listagg(p.name, '|') within group (order by p.product_id) as products
from (
    select item,
        regexp_substr(trim(',' from products), '[^,]+', 1, level) as product_id
    from item connect by prior item = item
        and level <= regexp_count(trim(',' from products), ',') + 1
        and prior sys_guid() is not null
    ) i
left join products p on i.product_id = p.product_id
group by i.item;

首先,需要拆分这个逗号分隔的字符串,并将单个字符串作为行给出。使用此选项:

select distinct ITEM_ID
        ,regexp_substr(PRODUCTS, '[^,]+', 1, level) PRODUCT_ID
    from item connect by regexp_substr(PRODUCTS, '[^,]+', 1, level) is not null
使用上面的查询作为表,可以与主表联接

select I.ITEM_ID
    ,P.PRODUCT_NAME
from ITEM I
inner join (
    select distinct ITEM_ID
        ,regexp_substr(PRODUCTS, '[^,]+', 1, level) PRODUCT_ID
    from item connect by regexp_substr(PRODUCTS, '[^,]+', 1, level) is not null
    ) X on X.ITEM_ID = I.ITEM_ID
inner join PRODUCTS P on P.PRODUCT_ID = X.PRODUCT_ID

这是一个错误的DB设计。表中不应该有逗号分隔的值,这是不利于规范化的。您的表甚至不是第一标准格式。@Apato03-您使用的是哪一版本的Oracle?理解并同意;它不是来自我们设计或控制的数据库。@GurV Oracle DB 11.2.0.3.0您所连接的数据库将无法在多行中正常工作。
select I.ITEM_ID
    ,P.PRODUCT_NAME
from ITEM I
inner join (
    select distinct ITEM_ID
        ,regexp_substr(PRODUCTS, '[^,]+', 1, level) PRODUCT_ID
    from item connect by regexp_substr(PRODUCTS, '[^,]+', 1, level) is not null
    ) X on X.ITEM_ID = I.ITEM_ID
inner join PRODUCTS P on P.PRODUCT_ID = X.PRODUCT_ID