2011-07-07 35 views
6

Tengo una tabla que tiene algunos hijos de un objeto maestro. Cualquier niño puede ocurrir más de una vez, y hay una columna de ocurrencias que contiene ese número, por lo que los datos de la tabla es algo así como:Seleccionar la misma fila varias veces

ChildID | ParentID | Occurences 
------------------------------- 
     1 |  1 |  2 
     2 |  1 |  2 
     3 |  2 |  1 
     4 |  2 |  3 

que necesito para obtener una lista de todos los niños, con cada niño aparece el número de veces que corect en el resultado, algo así como

IDENT | ChildID | ParentID 
-------------------------- 
    1 |  1 |  1 
    2 |  1 |  1 
    3 |  2 |  1 
    4 |  2 |  1 
    5 |  3 |  2 
    6 |  4 |  2 
    7 |  4 |  2 
    8 |  4 |  2 

puedo hacer esto con un cursor que recorre la tabla e inserta tantas filas donde sea necesario, pero no creo que esa es la mejor solución posible.

Gracias por la ayuda


Crear guión incluyen:

DECLARE @Children TABLE (ChildID int, ParentID int, Occurences int) 

INSERT @Children 
SELECT 1, 1, 2 UNION ALL 
SELECT 2, 1, 2 UNION ALL 
SELECT 3, 2, 1 UNION ALL 
SELECT 4, 2, 3 
+1

¿Le importa si le pregunto por qué necesita hacer esto? Tal vez hay una manera mejor que seleccionar la misma fila varias veces. – EdoDodo

+0

Necesito generar una fila para cada niño, porque hay algunos datos adicionales que pueden ser diferentes. – SWeko

Respuesta

7
;with C as 
(
    select ChildID, 
     ParentID, 
     Occurences - 1 as Occurences 
    from @Children 
    union all 
    select ChildID, 
     ParentID, 
     Occurences - 1 as Occurences 
    from C 
    where Occurences > 0 
) 
select row_number() over(order by ChildID) as IDENT, 
     ChildID, 
     ParentID 
from C 
order by IDENT 
+0

Thx, que hizo el truco – SWeko

+0

truco impresionante :) – SMK

+0

Una cosa más, en mi caso, el número de Occurences es pequeño (10 tops) pero si el número es de cientos, esto excederá el límite de recursión. – SWeko

4
;WITH CTEs 
AS 
(
    SELECT 1 [Id] 
    UNION ALL 
    SELECT [Id] + 1 FROM CTEs WHERE [Id] < 100 
) 
SELECT ROW_NUMBER() OVER(ORDER BY c1.ChildID, c1.ParentID) [rn] 
    , c1.ChildID, c1.ParentID 
FROM CTEs ct 
JOIN @Children c1 ON c1.Occurences >= ct.[Id] 

Otra manera de generar la secuencia está utilizando tabla predefinida, por ejemplo, master.dbo.spt_values:

SELECT ROW_NUMBER() OVER(ORDER BY c1.ChildID, c1.ParentID) [rn] 
    , c1.ChildID, c1.ParentID 
FROM master.dbo.spt_values ct 
JOIN @Children c1 ON c1.Occurences > ct.number 
    AND ct.type = 'P' 
+0

Genial, esto básicamente une la tabla fuente con una tabla de números, con una agradable condición de unión. – SWeko

+0

En mi caso, el número de observaciones es pequeño (10 tops) pero si el número es de cientos, esto excederá el límite de recursión. Eso podría eludirse si la tabla de números está pregenerada. – SWeko

+0

o eludido con "opción (MAXRECURSIÓN 0)" –

Cuestiones relacionadas