2010-09-08 14 views
10

Estoy usando Oracle para generar líneas de pedido desde una aplicación de compras. Cada elemento tiene un campo de cantidad que puede ser mayor que 1 y, si lo es, me gustaría devolver esa fila N veces.¿Cómo puedo devolver varias filas idénticas basadas en un campo de cantidad en la fila misma?

Esto es lo que estoy hablando de una mesa

product_id, quanity 
1, 3, 
2, 5 

Y estoy buscando una consulta que devolvería

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

Es esto posible? Vi this respuesta para SQL Server 2005 y estoy buscando casi lo mismo en Oracle. Construir una tabla de números dedicada desafortunadamente no es una opción.

Respuesta

15

He utilizado 15 como máximo para el ejemplo, pero debe establecerlo en 9999 o cualquiera que sea la cantidad máxima que admitirá.

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

gracias, esto es exactamente lo que estaba buscando. – user126715

4

En primer lugar crear datos de ejemplo:

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

Y ahora ejecutar este 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 

Esta pregunta es además probablemente mismo que esto: how to calc ranges in oracle

solución de actualización, por Oracle 9i:

Puede utilizar pipelined_function() así:

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

Ahora usted puede hacer esto:

SELECT * FROM TABLE(GET_DATA()); 

O esto:

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

Ambos con los mismos resultados.

(basado en mi artículo pipelined function)

+0

usas 11g? Nunca pude ejecutar la subconsulta en la cláusula 'connect by level' en 9i. –

+0

tiene razón, en Oracle 9i aumenta el error: ORA-01473. Escribiré una mejor solución para Oracle 9i ... espere un minuto, actualizaré mi "respuesta" :) –

+0

ahora la respuesta se ha actualizado para la solución Oracle 9i. –

Cuestiones relacionadas