none
Duplicar ultimo registro de una columna

    Pregunta

  • Hola a todos, tengo el siguiente problema, tengo la siguiente tabla:

    Fecha Codigo Hbc Contar
    28/02/2018 80854919 11.7 1
    27/05/2018 80854919 11.7 2
    17/07/2018 80854919 0 3
    13/09/2018 80854919 9.7 4
    04/01/2018 79941161 0 1
    04/02/2018 79941161 11.4 2
    01/03/2018 79941161 0 3
    05/03/2018 79941161 0 4

    se puede notar que algunos campos estan con 0 y quiero el ultimo Hbc llene los campos hasta el siguiente, y quede de la sgte manera:

    Fecha Codigo Hbc Contar
    28/02/2018 80854919 11.7 1
    27/05/2018 80854919 11.7 2
    17/07/2018 80854919 11.7 3
    13/09/2018 80854919 9.7 4
    04/01/2018 79941161 11.4 1
    04/02/2018 79941161 11.4 2
    01/03/2018 79941161 11.4 3
    05/03/2018 79941161 11.4 4

    Por favor, espero su ayuda.

    miércoles, 22 de mayo de 2019 16:43

Respuestas

  • Hola devy1451:

    A priori esa no es una formula para acometer con un lenguaje declarativo como SQL Server.

    Es claro que existen muchas maneras de hacerlo, también en SQL Server, pero la matemática de conjuntos no funciona de ese modo.

    Te expongo una de las múltiples soluciones, sin recaer en un simple bucle while que te permitiría hacer eso de un modo aceptable:

    Por cierto la primera fila del 11,4 no es 11.4 sino 9.7, ya que su valor anterior es ese.

    DROP TABLE IF EXISTS dbo.datos;
    
    CREATE TABLE dbo.datos
    ( Fecha  DATE
    , Codigo INT
    , Hbc    FLOAT
    , Contar INT
    );
    GO
    
    INSERT INTO dbo.datos
    ( Fecha
    , Codigo
    , Hbc
    , Contar
    )
    VALUES      
    ('28/02/2018', 80854919, 11.7, 1), 
    ('27/05/2018', 80854919, 11.7, 2), 
    ('17/07/2018', 80854919, 0, 3), 
    ('13/09/2018', 80854919, 9.7, 4),
    ('04/01/2018', 79941161, 0, 1), 
    ('04/02/2018', 79941161, 11.4, 2), 
    ('01/03/2018', 79941161, 0, 3), 
    ('05/03/2018', 79941161, 0, 4);
    GO
    /* INICIO DE LA CONSULTA.*/

    ----

    DECLARE @TABLE TABLE
    (ID     INT IDENTITY(1, 1)
    , Fecha  DATE
    , Codigo INT
    , Hbc    FLOAT
    , Contar INT
    );
    
    INSERT INTO @table
    	  SELECT datos.Fecha
    		  , datos.Codigo
    		  , datos.Hbc
    		  , datos.Contar
    	  FROM   
    		  dbo.datos;
    
    WITH CTE
    	AS (SELECT ID
    		    , FECHA
    		    , CODIGO
    		    , HBC
    		    , HBC AS DUPLICADO
    		    , CONTAR
    	    FROM   
    		    @TABLE T)
    	UPDATE T
    	  SET     
    	   HBC = CASE WHEN C.Hbc > 0
    				   THEN C.HBC
    			    ELSE
    	(
    	    SELECT HBC
    	    FROM   
    		    @TABLE M
    	    WHERE  M.ID =
    	    (
    		   SELECT MAX(S.ID)
    		   FROM   
    			   @TABLE S
    		   WHERE  S.ID < T.ID
    				AND HBC <> 0
    	    )
    	)
    		    END
    	FROM   @TABLE T
    			  INNER JOIN CTE C ON T.ID = C.ID;
    
    UPDATE s
      SET     
       s.Hbc = t.Hbc
    FROM   dbo.datos s
    		  INNER JOIN @TABLE t ON s.Fecha = t.Fecha
    							AND s.Codigo = t.Codigo
    							AND t.Contar = s.Contar
    WHERE  s.Hbc = 0;
    
    SELECT datos.Fecha
    	, datos.Codigo
    	, datos.Hbc
    	, datos.Contar
    FROM   
    	dbo.datos;
    Salida

    Elementos utilizados

    Tablas de expresión común

    https://javifer2.blogspot.com/search/label/tablas%20de%20expresi%C3%B3n%20com%C3%BAn%20%281%29

    Variable de tabla

    https://javifer2.blogspot.com/search/label/variables%20de%20Tabla

    miércoles, 22 de mayo de 2019 19:25

Todas las respuestas

  • Hola  

    Gracias por levantar tu consulta en los foros de MSDN. Con respecto a la misma, te hago la recomendación de ingresar al siguiente enlace en donde puedes encontrar una posible solución para tu problema.

    https://social.msdn.microsoft.com/Forums/es-ES/ed4054e0-94b5-489b-bdaf-534fb388b494/duplicar-registro-en-base-de-datos?forum=netfxwebes

    https://social.msdn.microsoft.com/Forums/es-ES/1daa7d64-155e-4c49-8ffd-76b6de89bbcf/insert-de-una-tabla-a-otra-sin-duplicar-registros?forum=sqlserveres

    https://social.msdn.microsoft.com/Forums/es-ES/c30181e8-eac5-4ff5-8520-7ea15129370d/duplicar-registro-sql-server?forum=sqlserveres

    Gracias por usar los foros de MSDN.

    Carlos Ruiz
     ____

    Por favor recuerde "Marcar como respuesta" las respuestas que hayan resuelto su problema, es una forma común de reconocer a aquellos que han ayudado, y hace que sea más fácil para los otros visitantes encontrar la solución más tarde. 

    Microsoft ofrece este servicio de forma gratuita, con la finalidad de ayudar a los usuarios y la ampliación de la base de datos de conocimientos relacionados con los productos y tecnologías de Microsoft.  

    Este contenido es proporcionado "tal cual" y no implica ninguna responsabilidad de parte de Microsoft.

    • Propuesto como respuesta Carlos_Ruiz_M miércoles, 22 de mayo de 2019 18:30
    miércoles, 22 de mayo de 2019 18:29
  • Hola devy1451:

    A priori esa no es una formula para acometer con un lenguaje declarativo como SQL Server.

    Es claro que existen muchas maneras de hacerlo, también en SQL Server, pero la matemática de conjuntos no funciona de ese modo.

    Te expongo una de las múltiples soluciones, sin recaer en un simple bucle while que te permitiría hacer eso de un modo aceptable:

    Por cierto la primera fila del 11,4 no es 11.4 sino 9.7, ya que su valor anterior es ese.

    DROP TABLE IF EXISTS dbo.datos;
    
    CREATE TABLE dbo.datos
    ( Fecha  DATE
    , Codigo INT
    , Hbc    FLOAT
    , Contar INT
    );
    GO
    
    INSERT INTO dbo.datos
    ( Fecha
    , Codigo
    , Hbc
    , Contar
    )
    VALUES      
    ('28/02/2018', 80854919, 11.7, 1), 
    ('27/05/2018', 80854919, 11.7, 2), 
    ('17/07/2018', 80854919, 0, 3), 
    ('13/09/2018', 80854919, 9.7, 4),
    ('04/01/2018', 79941161, 0, 1), 
    ('04/02/2018', 79941161, 11.4, 2), 
    ('01/03/2018', 79941161, 0, 3), 
    ('05/03/2018', 79941161, 0, 4);
    GO
    /* INICIO DE LA CONSULTA.*/

    ----

    DECLARE @TABLE TABLE
    (ID     INT IDENTITY(1, 1)
    , Fecha  DATE
    , Codigo INT
    , Hbc    FLOAT
    , Contar INT
    );
    
    INSERT INTO @table
    	  SELECT datos.Fecha
    		  , datos.Codigo
    		  , datos.Hbc
    		  , datos.Contar
    	  FROM   
    		  dbo.datos;
    
    WITH CTE
    	AS (SELECT ID
    		    , FECHA
    		    , CODIGO
    		    , HBC
    		    , HBC AS DUPLICADO
    		    , CONTAR
    	    FROM   
    		    @TABLE T)
    	UPDATE T
    	  SET     
    	   HBC = CASE WHEN C.Hbc > 0
    				   THEN C.HBC
    			    ELSE
    	(
    	    SELECT HBC
    	    FROM   
    		    @TABLE M
    	    WHERE  M.ID =
    	    (
    		   SELECT MAX(S.ID)
    		   FROM   
    			   @TABLE S
    		   WHERE  S.ID < T.ID
    				AND HBC <> 0
    	    )
    	)
    		    END
    	FROM   @TABLE T
    			  INNER JOIN CTE C ON T.ID = C.ID;
    
    UPDATE s
      SET     
       s.Hbc = t.Hbc
    FROM   dbo.datos s
    		  INNER JOIN @TABLE t ON s.Fecha = t.Fecha
    							AND s.Codigo = t.Codigo
    							AND t.Contar = s.Contar
    WHERE  s.Hbc = 0;
    
    SELECT datos.Fecha
    	, datos.Codigo
    	, datos.Hbc
    	, datos.Contar
    FROM   
    	dbo.datos;
    Salida

    Elementos utilizados

    Tablas de expresión común

    https://javifer2.blogspot.com/search/label/tablas%20de%20expresi%C3%B3n%20com%C3%BAn%20%281%29

    Variable de tabla

    https://javifer2.blogspot.com/search/label/variables%20de%20Tabla

    miércoles, 22 de mayo de 2019 19:25
  • Hola, gracias por tu aporte, me ayudará a solucionar otros muchos problemas, en cuanto al dato q corriges, son 2 grupos distintos, de hecho y hay muchos mas, como no tiene un primer dato ingresado tiene q tomar el siguiente, por lo q tiene q ser 11.4. El campo "contar" indica la cantidad y el orden de ingreso.
    jueves, 23 de mayo de 2019 17:46
  • Hola:

    Si tiene que tomar el siguiente, entonces el registro 3 debiera de ser 9.7 ¿no?

    Siempre puedes plantearte utilizar un cursor, no es santo de mi devoción, pero a veces cuando las cosas no están del todo claras o no encajan, y hay que hacerlo aunque sea a "calzador"

    Cursor

    http://www.devjoker.com/contenidos/articulos/240/Cursores-en-Transact-SQL.aspx





    • Propuesto como respuesta Carlos_Ruiz_M viernes, 24 de mayo de 2019 18:37
    jueves, 23 de mayo de 2019 18:02
  • Hola, si emplee un cursor, pero toma el ultima valor que se registro lo reemplaza a todos los anteriores, asi sea 0, necesito idear mejor la forma del cursor de tal manera q pueda hacer lo q necesito.
    viernes, 24 de mayo de 2019 16:36
  • Pero dentro del cursor, puedes aplicar la lógica que tu quieras.

    Declaras variables, y utilizas sentencias condicionales, del tipo si lo que me viene en el registro es 0 entonces le aplico @anterior.

    Lo más importante, para poder hacerlo de una sola pasada es precisamente, que la select del cursor tiene que estar ordenada a la inversa.

    Obvias los últimos 0, que luego lo arreglas con una update.

    Y coges el ultimo que en este caso es 11.4 contar=2 y le asignas este valor a una variable, en el siguiente registro, le asignas como es 0 lo de esa variable, en el siguiente como no es 0 lo dejas y cambias el valor de la variable.....

    A la salida del cursor updateas todos los registros que sean 0 y superiores al ultimo valor que no sea 0, por ese ultimo valor.

    viernes, 24 de mayo de 2019 18:52