How can I return multiple identical rows based on a quantity field in the row itself? How can I return multiple identical rows based on a quantity field in the row itself? oracle oracle

How can I return multiple identical rows based on a quantity field in the row itself?


I've used 15 as a maximum for the example, but you should set it to 9999 or whatever the maximum quantity you will support.

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.quantityorder by 1;


First create sample data:

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);

And now run this 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.quantityORDER BY product_id, lvl;PRODUCT_ID   QUANTITY---------- ----------         1          3         1          3         1          3         2          5         2          5         2          5         2          5         2          5

This question is propably same as this: how to calc ranges in oracle

Update solution, for Oracle 9i:

You can use pipelined_function() like this:

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 SampleTypeSetPIPELINEDIS    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;/

Now you can do this:

SELECT * FROM TABLE(GET_DATA());

Or this:

CREATE OR REPLACE VIEW VIEW_ALL_DATA AS SELECT * FROM TABLE(GET_DATA());SELECT * FROM VIEW_ALL_DATA;

Both with same results.

(Based on my article pipelined function)