我正在使用oracle从购物应用中输出订单项。每个项目的数量字段可能大于1,如果是,我想将该行返回N次。
这就是我所说的桌子
product_id, quanity
1, 3,
2, 5
我正在寻找一个会返回的查询
1,3
1,3
1,3
2,5
2,5
2,5
2,5
2,5
这可能吗?我看到了SQL Server 2005的this答案,我正在寻找oracle中的确切内容。遗憾的是,建立专用号码表不是一种选择。
答案 0 :(得分:15)
我在示例中使用了15作为最大值,但您应将其设置为9999或您支持的最大数量。
create table t (product_id number, quantity number);
insert into t values (1,3);
insert into t values (2,5);
select t.*
from t
join (select rownum rn from dual connect by level < 15) a
on a.rn <= t.quantity
order by 1;
答案 1 :(得分:4)
首先创建样本数据:
create table my_table (product_id number , quantity number);
insert into my_table(product_id, quantity) values(1,3);
insert into my_table(product_id, quantity) values(2,5);
现在运行这个SQL:
SELECT product_id, quantity
FROM my_table tproducts
,( SELECT LEVEL AS lvl
FROM dual
CONNECT BY LEVEL <= (SELECT MAX(quantity) FROM my_table)) tbl_sub
WHERE tbl_sub.lvl BETWEEN 1 AND tproducts.quantity
ORDER BY product_id, lvl;
PRODUCT_ID QUANTITY
---------- ----------
1 3
1 3
1 3
2 5
2 5
2 5
2 5
2 5
这个问题与此相同:how to calc ranges in oracle
更新解决方案,适用于Oracle 9i :
你可以像这样使用pipelined_function():
CREATE TYPE SampleType AS OBJECT
(
product_id number,
quantity varchar2(2000)
)
/
CREATE TYPE SampleTypeSet AS TABLE OF SampleType
/
CREATE OR REPLACE FUNCTION GET_DATA RETURN SampleTypeSet
PIPELINED
IS
l_one_row SampleType := SampleType(NULL, NULL);
BEGIN
FOR cur_data IN (SELECT product_id, quantity FROM my_table ORDER BY product_id) LOOP
FOR i IN 1..cur_data.quantity LOOP
l_one_row.product_id := cur_data.product_id;
l_one_row.quantity := cur_data.quantity;
PIPE ROW(l_one_row);
END LOOP;
END LOOP;
RETURN;
END GET_DATA;
/
现在你可以这样做:
SELECT * FROM TABLE(GET_DATA());
或者这个:
CREATE OR REPLACE VIEW VIEW_ALL_DATA AS SELECT * FROM TABLE(GET_DATA());
SELECT * FROM VIEW_ALL_DATA;
两者都有相同的结果。
(根据我的文章pipelined function)