2010-09-08 13 views
10

Sto utilizzando oracle per l'output di elementi pubblicitari da un'app di shopping. Ogni articolo ha un campo quantità che può essere maggiore di 1 e se lo è, vorrei restituire quella riga N volte.Come posso restituire più righe identiche in base a un campo quantità nella riga stessa?

Ecco cosa sto parlando di un tavolo

product_id, quanity 
1, 3, 
2, 5 

E sto cercando una query che sarebbe tornato

1,3 
1,3 
1,3 
2,5 
2,5 
2,5 
2,5 
2,5 

è possibile? Ho visto la risposta this per SQL Server 2005 e sto cercando quasi la cosa esatta in Oracle. Purtroppo non è possibile costruire una tabella di numeri dedicata.

risposta

15

Ho usato 15 come massimo per l'esempio, ma dovresti impostarlo su 9999 o qualunque sia la quantità massima supportata.

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

grazie, questo è esattamente quello che stavo cercando. – user126715

4

Innanzitutto creare dati di esempio:

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

E ora eseguire questo 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 

Questa domanda è stata riordinata stesso di questo: how to calc ranges in oracle

soluzione di aggiornamento, per Oracle 9i:

È possibile utilizzare pipelined_function() in questo modo:

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

Ora si può fare questo:

SELECT * FROM TABLE(GET_DATA()); 

O questo:

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

Sia con gli stessi risultati.

(in base alla mia articolo pipelined function)

+0

usi 11g? Non sono mai stato in grado di eseguire la sottoquery nella clausola 'connect by level' in 9i. –

+0

hai ragione, su Oracle 9i raise error: ORA-01473. Scriverò una soluzione migliore per Oracle 9i ... aspetta un minuto, aggiornerò la mia "risposta" :) –

+0

ora la risposta è aggiornata per la soluzione Oracle 9i. –

Problemi correlati