PL / SQL:INSTR(),SUBSTR(),如何从多选列表中提取值

时间:2017-03-11 12:52:35

标签: sql oracle plsql oracle11g

以下情况给出: 表格命令o和产品p通过多选列表连接。

产品p:

  • 主键PRODUCT_ID类似" 101"
  • 存储购买价格,如" 9.25"

命令o:

  • 主键ORDER_ID类似" 123456"
  • 将所有包含的产品存储在一个名为prod的列中,例如":101:199:250:999:"
  • 将所有包含的单位价格存储在名为":10.0:25.0:30.5:125.25:"
  • 的价格列中

因此,例如,在123456的订单中,包括四种产品。 ID为101的产品已售出10.0$(购买价格为9.25$),ID为199的产品已售出25.0$,依此类推......

因此,对我来说最具挑战性的部分是从多选列表中提取所需的值。

我如何提取取决于订购产品的价格来回答问题,例如" id = 999的产品的平均销售价格是多少?"

我已尝试过类似的内容:

SELECT MOD(INSTR(o.products, ':999:'),3)  FROM orders o;

返回值的位置。

由于我不是PL/SQL程序员,我不知道如何继续这个问题...... 欢迎提出想法。

1 个答案:

答案 0 :(得分:0)

您可以在较大的查询中使用以下查询。或者,您可以一次性使用它来规范化数据。或两者兼而有之。

您承担两个冒号分隔的字符串的责任,这些字符串具有相同数量的令牌等(这是首先以正常形式拥有表格的100多个原因之一)。

with
     orders ( order_id, prod, prices ) as (
       select 123456, ':101:99:250:999:', ':10.0:25.0:30.5:125.25:' from dual union all
       select 1003  , ':101:999:'       , ':9.95:130.40:'           from dual
     )
select order_id,
       to_number(substr(prod, instr(prod, ':', 1, level) + 1, 
             instr(prod, ':', 1, level + 1) - instr(prod, ':', 1, level) - 1)) as prod_id,
       to_number(substr(prices, instr(prices, ':', 1, level) + 1, 
             instr(prices, ':', 1, level + 1) - instr(prices, ':', 1, level) - 1)) as price
from   orders
connect by level <= length(prod) - length(replace(prod, ':')) - 1
       and prior order_id = order_id
       and prior sys_guid() is not null
;

ORDER_ID  PROD_ID   PRICE
--------  -------  ------
    1003      101    9.95
    1003      999    30.4
  123456      101      10
  123456       99      25
  123456      250    30.5
  123456      999  125.25