none
Diferencia entre 2 registros consecutivos RRS feed

  • Pregunta

  • Buenas tardes, uso un sql server 2008 y quiero calcular la diferencia entre 2 registros consecutivos.. por ejemplo mi consulta me devuelve lo siguiente..

    Fecha hora valor
    21/02/2018 17:50:00 1367
    21/02/2018 17:40:00 1327
    21/02/2018 17:30:00 1375
    21/02/2018 17:20:00 1358
    21/02/2018 17:10:00 1339
    21/02/2018 17:00:00 1341
    21/02/2018 16:50:00 1268
    21/02/2018 16:40:00 1060
    21/02/2018 16:30:00 864
    21/02/2018 16:20:00 869

    Yo quisiera que me devuelva lo siguiente:

    Fecha hora valor Diferencia
    21/02/2018 17:50:00 1367 0
    21/02/2018 17:40:00 1327 40
    21/02/2018 17:30:00 1375 -48
    21/02/2018 17:20:00 1358 17
    21/02/2018 17:10:00 1339 19
    21/02/2018 17:00:00 1341 -2
    21/02/2018 16:50:00 1268 73
    21/02/2018 16:40:00 1060 208
    21/02/2018 16:30:00 864 196
    21/02/2018 16:20:00 869 -5

    Me podrian ayudar a armar la consulta? Orientarme como?

    Muchas gracias.

    Saludos

    miércoles, 21 de febrero de 2018 20:56

Respuestas

  • Hola , podrías utilizar funciones de ventana, 

    create table #pruebas
    (
    Fecha  datetime,
    Hora   time(4),
    valor  int
    )
    insert into #pruebas values ('20180221','17:50:00',1367)
    insert into #pruebas values ('20180221','17:40:00',1327)
    insert into #pruebas values ('20180221','17:30:00',1375)
    insert into #pruebas values ('20180221','17:20:00',1358)
    insert into #pruebas values ('20180221','17:10:00',1339)
    
    with CTE 
     
    as
    (  
     select 
      ROW_NUMBER() over(order by Hora desc) AS Row#,* from #pruebas a
    )  
    
    select a.fecha,a.hora,a.valor,a.valor-b.valor as diferencia from CTE a
    inner join cte b on a.row#=b.row#-1
    
    
    drop table #pruebas
    


    Votar es agradecer.
    Saludos.
    Lima-Perú



    miércoles, 21 de febrero de 2018 21:20

Todas las respuestas

  • Hola , podrías utilizar funciones de ventana, 

    create table #pruebas
    (
    Fecha  datetime,
    Hora   time(4),
    valor  int
    )
    insert into #pruebas values ('20180221','17:50:00',1367)
    insert into #pruebas values ('20180221','17:40:00',1327)
    insert into #pruebas values ('20180221','17:30:00',1375)
    insert into #pruebas values ('20180221','17:20:00',1358)
    insert into #pruebas values ('20180221','17:10:00',1339)
    
    with CTE 
     
    as
    (  
     select 
      ROW_NUMBER() over(order by Hora desc) AS Row#,* from #pruebas a
    )  
    
    select a.fecha,a.hora,a.valor,a.valor-b.valor as diferencia from CTE a
    inner join cte b on a.row#=b.row#-1
    
    
    drop table #pruebas
    


    Votar es agradecer.
    Saludos.
    Lima-Perú



    miércoles, 21 de febrero de 2018 21:20
  • A partir de la versión 2012 resolver el problema es muy sencillo mediante las funciones analíticas LAG/LEAD, en versiones anteriores puedes conseguir el mismo resultado, también de manera fácil, combinando las filas de la tabla consigo misma (SELF JOIN), por ejemplo:

    DECLARE @T table (fecha date, hora time(0), valor int);
    INSERT INTO @T VALUES
    ('20180221', '17:50:00', 1367),
    ('20180221', '17:40:00', 1327),
    ('20180221', '17:30:00', 1375),
    ('20180221', '17:20:00', 1358),
    ('20180221', '17:10:00', 1339),
    ('20180221', '17:00:00', 1341),
    ('20180221', '16:50:00', 1268),
    ('20180221', '16:40:00', 1060),
    ('20180221', '16:30:00', 864),
    ('20180221', '16:20:00', 869);
    
    WITH T AS
    (
        SELECT *, ROW_NUMBER() OVER(ORDER BY fecha, hora DESC) AS rn FROM @T
    )
    SELECT t1.fecha, t1.hora, COALESCE(t2.valor, t1.valor) - t1.valor AS Diferencia
    FROM T t1 LEFT JOIN T t2 ON t1.rn -1 = t2.rn
    GO

    miércoles, 21 de febrero de 2018 21:36
  • Buenas tardes, disculpen la demora para responder. No logre hacer funcionar la consulta, pero buscando me di cuenta que el servidor es 2005 y no 2008 como me habian informado. Sigo intentando resolverlo. Si logro hacerlo copio la respuesta. 

    Muchas gracias

    jueves, 22 de marzo de 2018 20:28
  • Hola CarinaVB:

    La respuesta que te ha dado Augusto1982 es correcta y valida para 2005

    Como ves el nivel de compatibilidad de la base de datos donde la he probado es 2005 y este es el resultado

    Es posible que tu base de datos este en un modo de compatilibad anterior.....

    Y Si no te funciona, que te dice el Sql Server.

    A lo mejor alguien te puede echar otro cable.

    Un saludo

    jueves, 22 de marzo de 2018 20:56
  • Hola Javi, gracias por tu respuesta.

    Ejecute esto..

    select @@version
    Microsoft SQL Server  2000 - 8.00.2039 (Intel X86)   May  3 2005 23:18:38   Copyright (c) 1988-2003 Microsoft Corporation  Enterprise Edition on Windows NT 5.2 (Build 3790: Service Pack 2) 

    Es un hosting, se ve que es viejo el server, pero ahora no tengo opcion.

    Saludos

    jueves, 22 de marzo de 2018 21:16
  • Hola CarinaVB::

    Eso es correcto tu sql server esta en version 2008, pero ¿y tu base de datos?

    Si te das cuenta en la primera imagen que te pongo, al hacer click en la base de datos en el explorador de objetos, sobre la base de datos y con el botón derecho en propiedades, sección Opciones, el nivel de compatibilidad tiene que ser 2008, porque puedes tener uno anterior, (por ejemplo 2000), y tu base de datos solo reconoce instrucciónes como si tu servidor fuera 2000. En claro, que no solo por tener el servidor en 2008, se compilan las sentencias para 2008.

    Además si te da error la sentencia, y pones cual es la salida exacta, siempre se puede intentar buscar otra solución.

    Saludos

    viernes, 23 de marzo de 2018 6:14
  • Hola JAvi, gracias por responder. La base esta en un hosting y cuando quiero ver las propiedades me dice que no tengo permisos.

    select cmptlevel from master.dbo.sysdatabases where name = 'climas'

    La respuesta es 80.

    Con respecto al error, es el siguiente:

    'Row_Number' is not a recognized function name.

    Muchas gracias


    • Editado CarinaVB viernes, 23 de marzo de 2018 18:43
    viernes, 23 de marzo de 2018 18:15
  • Hola CarinaVB:

    Eso puedes resolverlo creo que asi

    with CTE 
     
    as
    (  
    select count(*) as row#, b1.fecha, b1.Hora, b1.valor from #pruebas b1 , #pruebas b2
    where b1.hora <= b2.Hora and b1.Fecha = b2.Fecha
    group by b1.hora, b1.valor, b1.Fecha
    
    )  
    
    select a.fecha,a.hora,a.valor,a.valor-b.valor as diferencia from CTE a
    inner join cte b on a.row#=b.row#-1
    order by a.hora desc
    ;
    

    Como ves la parte del Row_Number la trampeas por una cuenta de la tabla contra si misma.

    Ya cuentas..

    Saludos


    viernes, 23 de marzo de 2018 18:54