viernes, 9 de abril de 2010

UTILIZAR LEVEL PARA DUPLICAR REGISTROS EN UNA CONSULTA

A veces nos interesa duplicar, triplicar o tener n copias de un mismo registro de la base de datos por cualquier motivo. Un ejemplo sería hacer n copias de la misma factura para un cliente.
Para abordar esto lo podemos hacer de muchas maneras, utilizando bucles en el código, con SQL sin intervención de ningún tipo de bucle u otras maneras que seguro sabréis ;).

En el siguiente ejemplo de enfoque de la solución he optado por SQL, ya que la motivación inicial era aplicarlo directamente en la consulta de obtención de datos para REPORTS 6.

Para simplificar el ejemplo supondremos que tenemos los siguientes datos en una tabla llamada Cliente con estos datos


Nombre Copias
----------- ---------

Jordi .......... 3
Pedro
........ 2
Elisa
.......... 4
Utilizaremos la tabla DUAL para obtener una cantidad ilimitada de registros, pero para el ejemplo lo limitaremos a 5 registros.


SELECT LEVEL Registro FROM DUAL CONNECT BY LEVEL <= 5

Nota: cuidado con ejecutar SELECT LEVEL Registro FROM DUAL CONNECT BY LEVEL > 0, ya que la generación de la tabla temporal se comerá toda la memoria. (con 40.322.423 registros mi portatil se quedó sin memoria virtual)

Esto nos generará un conjunto de registros que quedaría así:


Registro
------------
1
2
3
4
5
Efectuamos la unión entre las dos tablas para obtener el conjunto de registros indicados en el campo copias de la tabla cliente.


SELECT c.nombre, c.copias, d.registro
FROM cliente c,
( SELECT LEVEL registro
FROM DUAL
CONNECT BY LEVEL <= 5 ) d WHERE c.copias >= d.registro
El resultado que obtenemos:


NOMBRE COPIAS REGISTRO
-------------- ------------ ----------------JORDI ............3................. 1
JORDI ............3................. 2
JORDI ........... 3................. 3
PEDRO ..........2................. 1
PEDRO ..........2................. 2
ELISA ...........4.................. 1
ELISA ...........4
.................. 2
ELISA
...........4.................. 3
ELISA
.......... 4.................. 4