none
Insertar registros alternando filas de 2 tablas en una nueva tabla RRS feed

  • Pregunta

  • Tenemos 2 tablas distintas, una para tipo D, otra para tipo A.

    table 1 = type D
    
        +-----+--------+
        |  tp |  name  |
        |-----+--------|
        |  D  |  10A   |
        |  D  |  11B   |
        |  D  |  12C   |
        +-----+--------+
    
    
    table 2 = type A
    
        +-----+--------+
        |  tp |  name  |
        |-----+--------|
        |  A  |  001   |
        |  A  |  002   |
        |  A  |  003   |
        |  A  |  004   |
        |  A  |  005   |
        +-----+--------+
    
    
    

    Se quiere insertar esos datos, en otra tabla (que tiene un ID identity), alternando las filas de ambas tablas:

    table final
    
        +-----+--------+
        |  tp |  name  |
        |-----+--------|
        |  A  |  001   |
        |  D  |  10A   |
        |  A  |  002   |
        |  D  |  11B   |
        |  A  |  003   |
        |  D  |  12C   |
        |  A  |  004   |
        |  A  |  005   |
        +-----+--------+
    

    Es posible hacer una inserción de dos tablas en una, de esa manera, alternando filas?

    Si NO fuera posible, podemos insertar todos los registros de tabla 1 en tabla Final, y después los registros de tabla 2 en tabla Final, y poder obtener una consulta alternando las filas?

    lunes, 20 de septiembre de 2021 18:43

Respuestas

  • Hola Miriam Pasión:

    El escenario que planteas:

    CREATE TABLE dbo.TYPED(tp char(1), name char(3));
    GO
    CREATE TABLE dbo.TYPEA (tp char(1), name char(3));
    GO
    CREATE TABLE dbo.TypeFinal(id int identity(1,1), tp char(1), name char(3));
    GO
    
    INSERT INTO dbo.TYPEA(tp, name)
    VALUES
    ('D','10A'),
    ('D','11B'),
    ('D','12C');
    GO
    INSERT INTO dbo.TYPED(tp, name)
    VALUES
    ('A','001'),
    ('A','002'),
    ('A','003'),
    ('A','004'),
    ('A','005');
    GO

    La solución más simple es utilizar row_number para numerar las filas, y el operador union all, para devolverlas en un solo conjunto.

    ;WITH T AS (
    	SELECT 
    	  ROW_NUMBER () OVER(ORDER BY NAME) AS ROW
    	  -- el order by podría ser tal que
    	  --ROW_NUMBER () OVER(ORDER BY (SELECT NULL)) AS ROW
    	, TP
    	, NAME
    	, 0 as dataRow
    	FROM dbo.TYPED
    	union all
    SELECT 
    	  ROW_NUMBER () OVER(ORDER BY NAME) AS ROW
    	  -- el order by podría ser tal que
    	  --ROW_NUMBER () OVER(ORDER BY (SELECT NULL)) AS ROW
    	, TP
    	, NAME
    	, 1 as dataRow
    	FROM dbo.TYPEA
    )
    SELECT *
    	FROM T 
    order by ROW, dataRow

    Dentro del conjunto T, leemos numeradas las filas de TypeD y ordenadas por name, o sin orden establecido, las filas del mismo. Luego unimos de la misma manera las filas del conjunto TypeA. Añadimos además una columna adicional para poder establecer primero las de typeA.

    Como se ve en la imagen, row_Number nos da el mismo número de fila, para las filas coincidentes de A y D. Y dataRow nos permite establecer la prioridad de un conjunto sobre otro.

    Solución

    ;WITH T AS (
    	SELECT 
    	  ROW_NUMBER () OVER(ORDER BY NAME) AS ROW
    	  -- el order by podría ser tal que
    	  --ROW_NUMBER () OVER(ORDER BY (SELECT NULL)) AS ROW
    	, TP
    	, NAME
    	, 0 as dataRow
    	FROM dbo.TYPED
    	union all
    SELECT 
    	  ROW_NUMBER () OVER(ORDER BY NAME) AS ROW
    	  -- el order by podría ser tal que
    	  --ROW_NUMBER () OVER(ORDER BY (SELECT NULL)) AS ROW
    	, TP
    	, NAME
    	, 1 as dataRow
    	FROM dbo.TYPEA
    )
    Insert into dbo.TypeFinal(tp,name)
    SELECT T.tp, T.name
    	FROM T 
    order by ROW, dataRow;

    Row Number

    https://javifer2.wordpress.com/2019/11/11/row-number-numerar-filas/

    • Marcado como respuesta Miriam Pasion martes, 21 de septiembre de 2021 5:45
    martes, 21 de septiembre de 2021 5:03