2010-09-08 22 views
10

我使用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 

這可能嗎?我看到this SQL Server 2005的答案,我正在尋找幾乎在oracle中的確切的東西。不幸的是,建立專用的數字表不是一種選擇。

回答

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

感謝,這正是我一直在尋找。 – user126715 2010-09-09 15:12:50

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 

這個問題,因爲這propably相同: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

+0

你使用11g嗎?我從來沒有能夠在9i的'connect by level'子句中運行子查詢。 – 2010-09-08 09:23:30

+0

你是對的,在Oracle 9i上引發錯誤:ORA-01473。我將爲Oracle 9i寫一個更好的解決方案...等我一分鐘,我會更新我的「答案」:) – 2010-09-08 09:38:49

+0

現在回答是針對Oracle 9i解決方案進行更新的。 – 2010-09-08 09:48:45

相關問題