PL/SQL:INSTR(),SUBSTR(),如何从多选列表中提取值
给出了以下情况: 订单o和产品p表通过多选列表连接 产品p: 主键产品\u ID类似于101 商店购买价格9.25美元 命令o: 主键顺序\u ID类似于123456 将所有包含的产品存储在一个名为prod like:101:199:250:999的列中: 在名为“价格”的列中存储所有包含的单价,如:10.0:25.0:30.5:125.25: 例如,订单123456包括四种产品。id为101的产品售价为10.0美元,而购买价格为9.25美元,id为199的产品售价为25.0美元,依此类推 因此,对我来说,最具挑战性的部分是从multiselect列表中提取所需的值 如何提取与订购产品相关的价格,以回答id=999的产品的平均销售价格是多少等问题 我已经试过这样的方法:PL/SQL:INSTR(),SUBSTR(),如何从多选列表中提取值,sql,oracle,plsql,oracle11g,Sql,Oracle,Plsql,Oracle11g,给出了以下情况: 订单o和产品p表通过多选列表连接 产品p: 主键产品\u ID类似于101 商店购买价格9.25美元 命令o: 主键顺序\u ID类似于123456 将所有包含的产品存储在一个名为prod like:101:199:250:999的列中: 在名为“价格”的列中存储所有包含的单价,如:10.0:25.0:30.5:125.25: 例如,订单123456包括四种产品。id为101的产品售价为10.0美元,而购买价格为9.25美元,id为199的产品售价为25.0美元,依此类推 因此
SELECT MOD(INSTR(o.products, ':999:'),3) FROM orders o;
返回值的位置
由于我不是PL/SQL程序员,我不知道如何继续讨论这个问题。。。
欢迎提出意见。您可以在更大的查询中使用下面的查询。或者,您可以使用它一次性地规范化数据。或者两者兼而有之 您将负责两个冒号分隔的字符串,它们具有相同数量的令牌等。这是将表设置为正常形式的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
首先,您不应该在单个列中存储多个分隔值。阅读数据库规范化是的,我知道这一点……使用第三个表,其中包含order_id和product_id键会更有效。不过,解决方案应该基于multiselect列表……:-/这不起作用。我相信这方面的聪明人可以提供一些可以工作的功能代码;但一旦你试图扩展这个系统,就会出现问题。所以,真正的答案是修复设计。请告诉我这是一个学校作业,而不是一个正在生产的系统somewhere@APC如果它在某个地方生产,不会持续太久。