none
Resta y formato de fechas sql server RRS feed

  • Pregunta

  • Buenos dias compañeros tengo este trigger que realiza la operacion de resta entre dos fechas el resultado me lo de en minutos, pero quisiera saber si se puede que me lo de en años,meses,dias y horas, un ejemplo

    6/27/2017- 6/26/2016= 1y,1m,1d, 11h

    CREATE TRIGGER tgcalculartiempo
        ON Test
        AFTER UPDATE
    AS
    BEGIN
        UPDATE f
        SET f.tiempo = DATEDIFF(minute, f.fechaentrega , f.fechapromesa) % 60
        
        FROM inserted i INNER JOIN productcompra f ON i.ID= f.ID
        WHERE f.tiempo IS NULL
    END

    jueves, 29 de junio de 2017 16:57

Respuestas

  • Saludos,

    Seria algo como esto : 

    CREATE TRIGGER tgcalculartiempo
        ON Test
        AFTER UPDATE
    AS
    BEGIN
        UPDATE f
        SET f.tiempo = DATEDIFF(year, f.fechaentrega , f.fechapromesa) +  DATEDIFF(minute, f.fechaentrega , f.fechapromesa) +  DATEDIFF(day, f.fechaentrega , f.fechapromesa) +  DATEDIFF(hour, f.fechaentrega , f.fechapromesa)
        FROM inserted i INNER JOIN productcompra f ON i.ID= f.ID
        WHERE f.tiempo IS NULL
    END


    Si mi respuesta te ha ayudado a resolver tus problemas, Selecciona "Proponer como respuesta"

    Blog
    J.Joaquin

    • Marcado como respuesta AlexP5 jueves, 29 de junio de 2017 19:23
    jueves, 29 de junio de 2017 17:31
  • No me queda claro lo que requieres:

    - ¿Un literal bajo el formato '1y, 1m, 1d, 11h'?

    Se entiende que el literal se asigna a una columna de tipo varchar() o similares:

    CREATE TRIGGER dbo.tgcalculartiempo
        ON dbo.Test
        AFTER UPDATE
    AS
    BEGIN
        WITH FechaBase(ID, Fecha) AS
        (
    	   SELECT f.ID, DATEADD(MINUTE, DATEDIFF(MINUTE, p.fechaentrega, p.fechapromesa), 0)
    	   FROM inserted i INNER JOIN productcompra f ON i.ID = f.ID
        )
        UPDATE f
        SET f.ColTexto = CONCAT(T.Años, 'y,', T.Meses, 'm,', T.Dias, 'd,', T.Horas, 'h')
        FROM 
    	   inserted i 
    	   INNER JOIN productcompra f ON i.ID = f.ID
    	   INNER JOIN FechaBase fb ON f.ID = fb.ID
    	   CROSS APPLY (VALUES(YEAR(fb.Fecha) - 1900, MONTH(fb.Fecha) - 1, DAY(fb.Fecha), 
    	   DATEPART(HOUR, fb.Fecha))) AS T (Años, Meses, Dias, Horas)	   
        WHERE f.tiempo IS NULL
    END
    GO

    - ¿Un valor de tipo datetime que contenga 1/1/1 11:0:0?

    El valor de fecha 1/1/1 no es válido para un tipo datetime, podrías considerar el valor por defecto del tipo datetime: '19000101' y agregarle los minutos para obtener una nueva fecha, por ejemplo:

    DATEADD(MINUTE, DATEDIFF(MINUTE, p.fechaentrega, p.fechapromesa), 0)
    --Resultado: 19000201

    Claro, al resultado habrá que restarle 1900 años y un mes tal como se muestra en el primer ejemplo adjunto.


    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.

    • Marcado como respuesta AlexP5 jueves, 29 de junio de 2017 19:12
    jueves, 29 de junio de 2017 18:22
  • ¿Has hecho algún cambio al código propuesto?. Imagino que el tipo para las columnas 'fechaentrega' y 'fechapromesa' es datetime, ¿verdad?

    Actualiza la definición del trigger:

    ALTER TRIGGER dbo.tgcalculartiempo
        ON dbo.Test
        AFTER UPDATE
    AS
    BEGIN
        WITH FechaBase(ID, Fecha) AS
        (
    	   SELECT f.ID, DATEADD(MINUTE, DATEDIFF(MINUTE, f.fechaentrega, f.fechapromesa), 0)
    	   FROM inserted i INNER JOIN productcompra f ON i.ID = f.ID
        )
        UPDATE f
        SET f.tiempo = CONCAT(T.Años, 'y,', T.Meses, 'm,', T.Dias, 'd,', T.Horas, 'h')
        FROM 
    	   inserted i 
    	   INNER JOIN productcompra f ON i.ID = f.ID
    	   INNER JOIN FechaBase fb ON f.ID = fb.ID
    	   CROSS APPLY (VALUES(YEAR(fb.Fecha) - 1900, MONTH(fb.Fecha) - 1, DAY(fb.Fecha) - 1, 
    	   DATEPART(HOUR, fb.Fecha))) AS T (Años, Meses, Dias, Horas)	   
        WHERE f.tiempo IS NULL
    END
    GO


    He creado una tabla de ejemplo con dos filas y el resultado es el esperado:


    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    • Marcado como respuesta AlexP5 jueves, 29 de junio de 2017 21:32
    jueves, 29 de junio de 2017 19:28

Todas las respuestas

  • Saludos,

    Seria algo como esto : 

    CREATE TRIGGER tgcalculartiempo
        ON Test
        AFTER UPDATE
    AS
    BEGIN
        UPDATE f
        SET f.tiempo = DATEDIFF(year, f.fechaentrega , f.fechapromesa) +  DATEDIFF(minute, f.fechaentrega , f.fechapromesa) +  DATEDIFF(day, f.fechaentrega , f.fechapromesa) +  DATEDIFF(hour, f.fechaentrega , f.fechapromesa)
        FROM inserted i INNER JOIN productcompra f ON i.ID= f.ID
        WHERE f.tiempo IS NULL
    END


    Si mi respuesta te ha ayudado a resolver tus problemas, Selecciona "Proponer como respuesta"

    Blog
    J.Joaquin

    • Marcado como respuesta AlexP5 jueves, 29 de junio de 2017 19:23
    jueves, 29 de junio de 2017 17:31
  • No me queda claro lo que requieres:

    - ¿Un literal bajo el formato '1y, 1m, 1d, 11h'?

    Se entiende que el literal se asigna a una columna de tipo varchar() o similares:

    CREATE TRIGGER dbo.tgcalculartiempo
        ON dbo.Test
        AFTER UPDATE
    AS
    BEGIN
        WITH FechaBase(ID, Fecha) AS
        (
    	   SELECT f.ID, DATEADD(MINUTE, DATEDIFF(MINUTE, p.fechaentrega, p.fechapromesa), 0)
    	   FROM inserted i INNER JOIN productcompra f ON i.ID = f.ID
        )
        UPDATE f
        SET f.ColTexto = CONCAT(T.Años, 'y,', T.Meses, 'm,', T.Dias, 'd,', T.Horas, 'h')
        FROM 
    	   inserted i 
    	   INNER JOIN productcompra f ON i.ID = f.ID
    	   INNER JOIN FechaBase fb ON f.ID = fb.ID
    	   CROSS APPLY (VALUES(YEAR(fb.Fecha) - 1900, MONTH(fb.Fecha) - 1, DAY(fb.Fecha), 
    	   DATEPART(HOUR, fb.Fecha))) AS T (Años, Meses, Dias, Horas)	   
        WHERE f.tiempo IS NULL
    END
    GO

    - ¿Un valor de tipo datetime que contenga 1/1/1 11:0:0?

    El valor de fecha 1/1/1 no es válido para un tipo datetime, podrías considerar el valor por defecto del tipo datetime: '19000101' y agregarle los minutos para obtener una nueva fecha, por ejemplo:

    DATEADD(MINUTE, DATEDIFF(MINUTE, p.fechaentrega, p.fechapromesa), 0)
    --Resultado: 19000201

    Claro, al resultado habrá que restarle 1900 años y un mes tal como se muestra en el primer ejemplo adjunto.


    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.

    • Marcado como respuesta AlexP5 jueves, 29 de junio de 2017 19:12
    jueves, 29 de junio de 2017 18:22
  • Disculpa compañero mi campo tiempo si es varchar y a ese campo es al que le voy asignar el resultado, me sale el siguiente error al probar el trigger:

    The multi-part identifier "p.fechaentrega" could not be bound.

    The multi-part identifier "p.fechapromesa" could not be bound.

    jueves, 29 de junio de 2017 18:58
  • WITH FechaBase(ID, Fecha) AS
        (
    	   SELECT f.ID, DATEADD(MINUTE, DATEDIFF(MINUTE, f.fechaentrega, f.fechapromesa), 0)
    	   FROM inserted i INNER JOIN productcompra f ON i.ID = f.ID
        )


    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    jueves, 29 de junio de 2017 19:04
  • Gracias compañero ya funciona pero me marca siempre 1d 0y,0m,1d,0h
    jueves, 29 de junio de 2017 19:13
  • Disculpa compañero el trigger que propones si pasan 4 minutos te pone 4 habria alguna forma de que pusiera si pasaron 4 minutos ponga 4m, si paso 5 horas ponga 5h
    jueves, 29 de junio de 2017 19:25
  • ¿Has hecho algún cambio al código propuesto?. Imagino que el tipo para las columnas 'fechaentrega' y 'fechapromesa' es datetime, ¿verdad?

    Actualiza la definición del trigger:

    ALTER TRIGGER dbo.tgcalculartiempo
        ON dbo.Test
        AFTER UPDATE
    AS
    BEGIN
        WITH FechaBase(ID, Fecha) AS
        (
    	   SELECT f.ID, DATEADD(MINUTE, DATEDIFF(MINUTE, f.fechaentrega, f.fechapromesa), 0)
    	   FROM inserted i INNER JOIN productcompra f ON i.ID = f.ID
        )
        UPDATE f
        SET f.tiempo = CONCAT(T.Años, 'y,', T.Meses, 'm,', T.Dias, 'd,', T.Horas, 'h')
        FROM 
    	   inserted i 
    	   INNER JOIN productcompra f ON i.ID = f.ID
    	   INNER JOIN FechaBase fb ON f.ID = fb.ID
    	   CROSS APPLY (VALUES(YEAR(fb.Fecha) - 1900, MONTH(fb.Fecha) - 1, DAY(fb.Fecha) - 1, 
    	   DATEPART(HOUR, fb.Fecha))) AS T (Años, Meses, Dias, Horas)	   
        WHERE f.tiempo IS NULL
    END
    GO


    He creado una tabla de ejemplo con dos filas y el resultado es el esperado:


    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    • Marcado como respuesta AlexP5 jueves, 29 de junio de 2017 21:32
    jueves, 29 de junio de 2017 19:28
  • gracias compañero lo volvi hacer y si funciono
    jueves, 29 de junio de 2017 21:20