none
Contar registros repetidos cada 72h en SQL Server RRS feed

  • Pregunta

  • quisiera pedir su apoyo , tengo una tabla con los siguientes campos:

    1. Codigo_cliente
    2. Fecha_hora
    3. Codigo_atencion


    Me piden que cuente a los clientes por cada 72 horas , quiere decir que si un cliente en las 72h realiza mas de una atención("n" veces) debería contar como 1 atención y si ese mismo cliente vuelve solicitar mas de una atención después de esas 72 h también de debe contar como 1 atención adicional .Tendrán alguna idea como realizar ese tipo de conteo por cada cliente. Gracias de antemano.

    lunes, 15 de abril de 2019 17:07

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/bd37abc0-277b-4e1b-8eba-099d33c6b912/contar-registros-repetidos-y-agruparlos-en-sql-server?forum=sqlserveres

    https://social.msdn.microsoft.com/Forums/es-ES/ad0edaed-8dca-4e64-ae92-17866f9b1973/contar-registros-repetidos?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.
    lunes, 15 de abril de 2019 18:39
  • No creo entender tu pregunta del todo, pero pudieras usar las funciones de off-set LAG/LEAD para comparar una fila con la anterior de acuerdo a un orden dado. Si han pasado 72 horas desdela anterior lo marcas para ser contado de lo contrario no.

    AMB

    Some guidelines for posting questions...

    AYÚDANOS A AYUDARTE, guía básica de consejos para formular preguntas

    lunes, 15 de abril de 2019 18:59
  • Hola  gracias por responde,uso sql server 2008 y no se activa las funciones LAG Y LEAD . 

    CODIGO FECHA_HORA CODIGO_ATENCION
    910124800 09/02/2019 9:46 48166903
    910124800 17/02/2019 15:48 48724405
    910160235 04/03/2019 16:41 49796093
    910160235 04/03/2019 17:46 49804436
    913348132 20/02/2019 8:23 48898795
    913348132 20/02/2019 8:36 48896777

    esta es mi tabla ,y  si un cliente tiene mas de una atención(codigo_atencion) dentro de las 72h deberia contar como 1 atención ,osea si el cliente tuvo 20 atenciones dentro de las 72horas deberias contar como 1 atencion . El problema que tengo es como agrupar comparando el rango de fechas .

    lunes, 15 de abril de 2019 20:01
  • Hola Renzo Lu:

    El escenario

    create table CODIGOS (CODIGO INT, FECHA_HORA DATETIME, CODIGO_ATENCION INT)
    GO
    INSERT INTO CODIGOS (CODIGO, FECHA_HORA, CODIGO_ATENCION)
    VALUES
    (910124800,'09/02/2019 9:46' ,48166903),
    (910124800,'17/02/2019 15:48',48724405),
    (910160235,'04/03/2019 16:41',49796093),
    (910160235,'04/03/2019 17:46',49804436),
    (913348132,'20/02/2019 8:23' ,48898795),
    (913348132,'20/02/2019 8:36' ,48896777);
    GO
    

    con la tabla creada tal cual presentas.

    WITH CTE
    	AS (
    	/* NUMERAMOS LAS FILAS */
    	SELECT ROW_NUMBER() OVER(PARTITION BY CODIGO
    			 ORDER BY CODIGO
    				   , FECHA_HORA DESC) AS FILA
    		    , CODIGO
    		    , FECHA_HORA
    		    , CODIGO_ATENCION
    	    FROM   
    		    CODIGOS
    ),R	AS (
    /* OBTENEMOS LA DIFERENCIA DE HORAS ENTRE LOS DOS CONJUNTOS FILA Y FILA ANTERIOR */
    	   SELECT C.CODIGO
    		    , C.FECHA_HORA
    		    , C.CODIGO_ATENCION
    		    , C2.CODIGO AS COD2
    		    , C2.FECHA_HORA AS C2FECHAHORA
    		    , C2.CODIGO_ATENCION AS C2CODATENCION
    		    , DATEDIFF(HOUR, C2.FECHA_HORA, C.FECHA_HORA) AS HORAS
    		    , C.FILA
    		    , C2.FILA AS FILA2
    	    FROM   
    		    CTE C
    			    LEFT JOIN CTE C2 ON C.FILA = C2.FILA - 1
    							    AND C.CODIGO = C2.CODIGO
    ),R2	AS (
    /* SACAMOS LA DIFERENCIA DE HORAS */
    		  SELECT R.CODIGO
    		    , R.FECHA_HORA
    		    , R.CODIGO_ATENCION
    		    , R.HORAS
    		    , R.FILA
    		    , R.FILA2
    		    , ISNULL(ANT.HORAS,0) AS ANTHORAS
    		    ,ANT.FILA ANTFILA
    	    FROM   
    		    R LEFT JOIN R AS ANT ON R.CODIGO = ANT.CODIGO AND R.FILA= ANT.FILA +1
    )
    /*EXTRAEMOS LOS RESULTADOS */
    	SELECT R2.CODIGO, R2.FECHA_HORA, R2.CODIGO_ATENCION
    	   FROM   R2 
    	   WHERE (FILA>1 AND ANTHORAS > 72)
    		  OR
    		  FILA= 1
    	   ORDER BY CODIGO

    Salida

    Espero te ayude

    martes, 16 de abril de 2019 20:11
  • Gracias a Javi por postear data de ejemplo.

    En su ejemplo, el codigo 910124800 realizo mas de una atencion, el resto solo una.

    SET DATEFORMAT DMY
    GO
    DECLARE @CODIGOS table (
    CODIGO INT, 
    FECHA_HORA DATETIME, 
    CODIGO_ATENCION int
    );
    
    INSERT INTO @CODIGOS (
        CODIGO, 
        FECHA_HORA, 
        CODIGO_ATENCION
        )
    VALUES
    (910124800,'09/02/2019 9:46' ,48166903),
    (910124800,'17/02/2019 15:48',48724405),
    (910160235,'04/03/2019 16:41',49796093),
    (910160235,'04/03/2019 17:46',49804436),
    (913348132,'20/02/2019 8:23' ,48898795),
    (913348132,'20/02/2019 8:36' ,48896777);
    
    WITH R1 AS (
    SELECT
    	CODIGO, FECHA_HORA, CODIGO_ATENCION,
        CASE
        WHEN DATEDIFF(HOUR, LAG(FECHA_HORA) OVER(PARTITION BY CODIGO ORDER BY FECHA_HORA), FECHA_HORA) > 72 THEN 1
        ELSE 0
        END AS grp_helper 
    FROM
    	@CODIGOS
    )
    , R2 AS (
    SELECT
    	CODIGO,
        FECHA_HORA,
        CODIGO_ATENCION,
        SUM(grp_helper) OVER(
        PARTITION BY CODIGO
        ORDER BY FECHA_HORA
        ROWS UNBOUNDED PRECEDING
        ) AS grp
    FROM
    	R1
    )
    SELECT
    	CODIGO,
        COUNT(DISTINCT grp) AS cnt
    FROM
    	R2
    GROUP BY
        CODIGO;
    GO
    SET DATEFORMAT MDY
    GO
    
    /*
    
    CODIGO	cnt
    910124800	2
    910160235	1
    913348132	1
    
    */

    Como sugeri antes, usamos la funcion off-set LAG para traer el valor de FECHA_HORA de la fila anterior y si la diferencia en horas entre la fila corriente y la anterior es mayor a 72 entonces la marcamos como inicio de grupo.  Luego contamos cuantos grupos tenemos por cada codigo.

    Aca otra solucion mas simple que usa misma logica. Solo se marca la primera fila por codigo asi como cada fila si han pasado 72 horas desde la atencion anterior.

    WITH R1 AS (
    SELECT
    	CODIGO, FECHA_HORA, CODIGO_ATENCION,
        LAG(FECHA_HORA) OVER(PARTITION BY CODIGO ORDER BY FECHA_HORA) AS prvFH
    FROM
    	@CODIGOS
    )
    , R2 AS (
    SELECT
    	CODIGO,
        FECHA_HORA,
        CODIGO_ATENCION,
        CASE WHEN DATEDIFF(HOUR, prvFH, FECHA_HORA) > 72 THEN 1 ELSE 0 END AS grp_helper,
        CASE WHEN prvFH IS NULL THEN 1 ELSE 0 END AS fInCod
    FROM
    	R1
    )
    SELECT
    	CODIGO,
        SUM(grp_helper + fInCod) AS cnt
    FROM
    	R2
    GROUP BY
        CODIGO;
    GO


    AMB

    Some guidelines for posting questions...

    AYÚDANOS A AYUDARTE, guía básica de consejos para formular preguntas


    • Editado HunchbackMVP miércoles, 17 de abril de 2019 18:17
    miércoles, 17 de abril de 2019 12:47
  • De nada
    miércoles, 17 de abril de 2019 16:07