Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » Mysql »

Contar clics únicos cada 30 minutos

Estas en el tema de Contar clics únicos cada 30 minutos en el foro de Mysql en Foros del Web. Buenos días, ¿Me podéis ayudar con este problema? Dispongo de una tabla donde registro los clics que hacen mis usuarios a mis productos. Pero me ...
  #1 (permalink)  
Antiguo 05/01/2013, 04:32
Avatar de neodani  
Fecha de Ingreso: marzo-2007
Mensajes: 1.811
Antigüedad: 17 años, 1 mes
Puntos: 20
Contar clics únicos cada 30 minutos

Buenos días,

¿Me podéis ayudar con este problema?

Dispongo de una tabla donde registro los clics que hacen mis usuarios a mis productos. Pero me gustaría poder filtrar los clics únicos de cada usuario, siendo clic único, un clic cada 30 minutos sobre un mismo producto.

Ej. si clican 10 veces en un producto y 5 veces en otro producto en menos de 30 minutos, solo contaría 2 clics.

Lo podría hacer vía programación web, solo insertando si ha pasado 30 minutos desde él ultimo clic. Pero no lo hago así porque me parece útil saber cuantos clics hace el usuario en el producto, aunque lo que quiero también es poder sacar los clics únicos.

La tabla tiene el formato
track_id | producto_id | user_id | marca_id | source | ip | fecha

Muchas gracias por adelantado
  #2 (permalink)  
Antiguo 05/01/2013, 09:34
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Cáceres
Mensajes: 3.735
Antigüedad: 16 años
Puntos: 300
Respuesta: Contar clics únicos cada 30 minutos

neodani, convierte la fecha a segundos, divide por 1800, que son los segundos de 30 minutos. A ver si me explico
agrupas los resultados por el valor entero superior (FLOOR(x)) de la operacion de dividir la fecha convertida a segundos TO_SECONDS(fecha) por 1800, que son los segundos de media hora.
No he probado nada y tampoco estoy seguro, pero se me ocurre algo así:
Código MySQL:
Ver original
  1.    user_id,
  2.    COUNT(DISTINCT producto_id) clics,
  3.     DATE_FORMAT(fecha, '%Y-%m-%d %H:%i:00')
  4. FROM tutabla
  5.        FLOOR(TO_SECONDS(fecha)/1800),  
  6.        user_id
  7. HAVING clics > 0

Última edición por jurena; 05/01/2013 a las 09:41
  #3 (permalink)  
Antiguo 05/01/2013, 10:20
Avatar de neodani  
Fecha de Ingreso: marzo-2007
Mensajes: 1.811
Antigüedad: 17 años, 1 mes
Puntos: 20
Respuesta: Contar clics únicos cada 30 minutos

Hola jurena,

La función que conozco para pasar una fecha a segundos, es la función de diferencia entre dos fechas que le puedes decir en que unidad, ejemplo con segundos sería así

SELECT TIMESTAMPDIFF(SECOND,'2013-01-01 11:00','2013-01-01 12:00');

Esto devolvería 3600 segundos

El problema es que no se como agrupar los resultados que hayan pasado mas de 30 minutos entre ellos. No veo por donde cogerlo, porque esta claro que la fecha a comparar no es la fecha actual, debe ser la fecha del siguiente registro...

Alguna ayuda?

Muchas gracias
  #4 (permalink)  
Antiguo 05/01/2013, 10:31
Avatar de neodani  
Fecha de Ingreso: marzo-2007
Mensajes: 1.811
Antigüedad: 17 años, 1 mes
Puntos: 20
Respuesta: Contar clics únicos cada 30 minutos

Parece que me funciona, de esta manera

Código MySQL:
Ver original
  1.    user_id,
  2.    COUNT(DISTINCT producto_id) clics
  3. FROM tracking_productos
  4.        FLOOR(visitdate/1800),
  5.        user_id
  6. HAVING clics > 0

Sin embargo, veo que me muestra una fila por cada 30 minutos de diferencia que hay entre la última vez que visitó el último producto.

USER_ID | CLICS
3 | 2
3 | 5
3 | 3
3 | 1
3 | 4

Habría forma de afinar la consulta y hacer que el resultado final fuese agrupado por USER_ID? es necesario una subquery para lograrlo?

Muchas gracias de antemano
  #5 (permalink)  
Antiguo 05/01/2013, 10:35
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Cáceres
Mensajes: 3.735
Antigüedad: 16 años
Puntos: 300
Respuesta: Contar clics únicos cada 30 minutos

Creo que mi propuesta no te soluciona, pues me hablas de diferencias de 30 minutos entre clics. Lo que te propuse resuelve si lo que te interesa es el número de clics cada 30 minutos, y no es el caso. Sin embargo, TO_SECONDS(fecha) te devuelve el valor en segundos de la fecha en que pulsó. Te resultará fácil al repasar el ciclo con programación contar sólo como valor ese que es posterior en 1800 segundos o más al anteriormente recogido para el mismo user_id y el mismo producto_id.
buscas el cliente y pides que te devuelva el user_id, el producto_id y TO_SECONDS(fecha). Ordenas por producto_id y fecha. Luego con programación creas una variable para sumar los clics (el primero lo sumas siempre). Al pasar compruebas si es el mismo producto que hayan pasado más de 1800 segundos, y sumas 1..., pero esto es programación. No has dicho si tienes un rango de fechas o un comienzo...
  #6 (permalink)  
Antiguo 05/01/2013, 17:03
Avatar de neodani  
Fecha de Ingreso: marzo-2007
Mensajes: 1.811
Antigüedad: 17 años, 1 mes
Puntos: 20
Respuesta: Contar clics únicos cada 30 minutos

Cita:
Iniciado por jurena Ver Mensaje
Creo que mi propuesta no te soluciona, pues me hablas de diferencias de 30 minutos entre clics. Lo que te propuse resuelve si lo que te interesa es el número de clics cada 30 minutos, y no es el caso. Sin embargo, TO_SECONDS(fecha) te devuelve el valor en segundos de la fecha en que pulsó. Te resultará fácil al repasar el ciclo con programación contar sólo como valor ese que es posterior en 1800 segundos o más al anteriormente recogido para el mismo user_id y el mismo producto_id.
buscas el cliente y pides que te devuelva el user_id, el producto_id y TO_SECONDS(fecha). Ordenas por producto_id y fecha. Luego con programación creas una variable para sumar los clics (el primero lo sumas siempre). Al pasar compruebas si es el mismo producto que hayan pasado más de 1800 segundos, y sumas 1..., pero esto es programación. No has dicho si tienes un rango de fechas o un comienzo...
Gracias jurena,

Sí, vía programación web sería posible.
Sin embargo, no hay ninguna forma de agruparlos? pues como puse en el comentario anterior, el resultado es bueno, pero se tendría que hacer "solo" un paso más que sería agrupar el resultado por user_id.

Eso con una subconsulta no se puede lograr?


PD: He descubierto porque no me funciona la función TO_SECONDS. Resulta que la versión instalada es la 5.1 y la función es de la 5.5 :D
  #7 (permalink)  
Antiguo 06/01/2013, 03:21
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Cáceres
Mensajes: 3.735
Antigüedad: 16 años
Puntos: 300
Respuesta: Contar clics únicos cada 30 minutos

Neodani,
vamos por partes:
1) Creo que hay una gran diferencia entre contar clics dentro de períodos fijos de 30 minutos, establecidos como tales, de media en media hora (es decir, de hora a hora y media), o contar solo como válidos los que se separan 30 minutos entre sí cuando hablamos del mismo producto, sin rangos de referencia horaria, sino como diferencia temporal entre ellos. En el primer caso un clic de un cliente para el producto a las y 12:29:00 y otro a las 13:01:00 sobre el mismo producto se contarían como dos clics, y en el segundo como solo uno, porque se separan entre sí dos minutos.
2) Yo lo haría con programación (es posible que con procedimientos pudieras hacerlo en la base), pero yo lo haría con mi programa porque no manejo mucho los procedimientos. El truco es usar bien el ORDER BY de la consulta. Tienes que ordenar la salida de la consulta así:
... ORDER BY user_id, producto_id, visit_date
Tan sencillo como eso en lo que se refiere a la base de datos. Y no es poco, como verás.
3) Para resolver el problema de la función TO_SECONDS, puedes usar TIMESTAMPDIFF (SECOND, unafechareferencia, visit_date), y cuando digo unafechareferencia me refiero a cualquier fecha con horas minutos y segundos anterior a todas tus fechas registradas; podrías usar por ejemplo el primer día del primer mes del año en su primera hora minuto y segundo, pero del año en que tienes ya resultados, aunque te valdría cualquier otra siempre que sea anterior a la más antigua que tienes registrada. Imaginemos que tus resultados parten de 2011, pues pones '2011-01-01 00:00:01' como fecha de referencia. No importará mucho la fecha que sea, pues lo que a ti te sirve es la diferencia entre el momento de un clic y del siguiente sobre un mismo producto. Veamos un ejemplo:
SELECT TIMESTAMPDIFF(SECOND,'2011-01-01 00:00:01', '2011-02-04 23:14:12')
esto da por ejemplo 3021251, que como valor absoluto no dice nada, pero que comparado con el de la siguiente pulsación sobre el mismo producto sí puede ser comparado para saber si es o no 1800 segundos anterior.
Bien, me dices que no puedes agrupar. Imagino que lo dices porque quieres sacar los resultados de cada cliente, es decir, de todos los clientes, de una vez, algo así como
user_id|clics|mes
1|52|1
2|25|1

entendiendo que en el mes de enero el usuario 1 ha pulsado 52 veces, pero esos clics solo se cuentan si es la primera vez que se hace clic sobre ese producto o han pasado al menos 1800 segundos respecto del anterior clic sobre dicho producto;

Hacer la consulta sobre el mismo cliente es fácil, con un WHERE user_id = 1, aunque puedes usar el mismo ORDER BY si bien quitando la parte del order referida a user_id. Pero el problema para ti parece ser cómo hacerlo sobre todos los clientes de una vez. Pues lanza la siguiente consulta para que veas el resultado de la consulta (he puesto el año 2010 como comienzo):

Código MySQL:
Ver original
  1.     user_id,
  2.     producto_id,
  3.     TIMESTAMPDIFF(SECOND,'2010-01-01 00-00-01',visit_date) segundos
  4.   FROM tracking_productos
  5.     ORDER BY
  6.        user_id,
  7.        producto_id,
  8.        visit_date

Esta consulta es solo la preparación. Lo demás lo resuelves con programación recorriendo los datos tal y como están y creando un array sobre el que cargas los valores que te interesa mostrar. Eso lo devuelves y lo muestras. Esto es de programación, Neodani, y allí podrán ayudarte si es que tienes alguna dificultad, pero te hablaré de la lógica, sin escribir nada de código (pido perdón por las aclaraciones y si nuestro moderador considera que debe quitarlas, comprenderé que lo haga).

Recorres esos datos habiendo creado una variable de control para user, otra para producto, otra para segundos, otra para clics, y un array en el que se cargará dentro del ciclo cada user_id y la suma de sus clics.
Bien, comparas así:
si user de la variable distinto de user_id que pasas, cargas el valor de user_id en user y sumas un clic a la variable clics y guardas el producto_id en producto y los segundos en la variable segundos; pasas al siguiente dato en el ciclo: si es el mismo user_id que el guardado en user, comparas el producto_id que te traes con el que tienes en producto y si es distinto, directamente sumas uno a clics y vuelves a actualizar los datos de las tres variables con los últimos recogidos; pero si tanto el user como el producto coincide, comparas los segundos y si son igual o mayor que 1800 añades 1 a clics. Cuando pasas a los datos del segundo user_id, al comparar y ver que se trata de un nuevo user, cargas los datos del user anterior y sus clics acumulados en el array, y actualizas los datos de las variables con los del nuevo user_id, producto_id, segundos, y actualizas los clics a 0, claro. Así hasta el último usuario (tendrás que ver el modo de que los datos del último también se carguen en el array con un control sobre el número de registros pasados, tal vez una variable, pero para todo esto pide ayuda en el foro de tu programa). Luego muestras el array. Es decir, el ciclo es para hacer la carga de ese array, y luego muestras el array. Pero esto tienes que programarlo.


4) Respecto a lo que preguntas sobre subconsultas, claro que podremos hacer algo, pero ahora interesa resolver primero cuál de las opciones del punto uno prefieres. Si es la segunda, la consulta que te propuse en mi primer post del hilo no te servirá, porque no te estará devolviendo los datos que buscas.

Es lo que se me ocurre.

Última edición por jurena; 06/01/2013 a las 17:20
  #8 (permalink)  
Antiguo 08/01/2013, 16:37
Avatar de neodani  
Fecha de Ingreso: marzo-2007
Mensajes: 1.811
Antigüedad: 17 años, 1 mes
Puntos: 20
Respuesta: Contar clics únicos cada 30 minutos

Wow Jurena,

Gracias por tus comentarios, la verdad es que vía programación web, sé que se puede hacer y la forma que planteas es mas o menos como me lo imaginaba de un principio.

Respecto al tipo de dato que necesito, es el ejemplo siguiente:

Persona A
Visita 3 productos diferentes en cualquier intervalo, contabiliza 3 clics

Persona B
Visita el producto 1 a las 11:00 y vuelve a visitarlo a las 11:10 y a las 11:20 y a las 11:30 y a las 11:40. Debería contar cómo 1 visita, partiendo de que una sesión es una interacción de un usuario con un site que termina a los 30 minutos de inactividad. En este caso, como no ha pasado 30 minuto desde el último clic en el producto 1, solo cuenta 1.

Persona C
Visita el producto 1 a las 11:00 y vuelve a visitarlo a la 11:35 y a las 12:00.
Debería contar 2 clics el primero y el segundo, pues el tercero estamos en el mismo ejemplo anterior, no ha pasado 30 minutos desde la última interacción del usuario con el producto.

Y esto me gustaría poderlo contabilizar sin tener que recurrir a la programación, sino a través de mysql vía subconsultas si es necesario.

El código del principio, contabiliza bien los clics, solo que no agrupa los resultados.

Código MySQL:
Ver original
  1.    user_id,
  2.    COUNT(DISTINCT producto_id) clics
  3. FROM tracking_productos
  4.        FLOOR(visitdate/1800),
  5.        user_id
  6. HAVING clics > 0

Muchas gracias
  #9 (permalink)  
Antiguo 09/01/2013, 13:47
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Cáceres
Mensajes: 3.735
Antigüedad: 16 años
Puntos: 300
Respuesta: Contar clics únicos cada 30 minutos

Neodani,
no he probado esto, pero quizás es lo que quieres.
Código MySQL:
Ver original
  1. SELECT t1.user_id, SUM(t1.clics) totclics FROM (SELECT
  2.    user_id,
  3.    COUNT(DISTINCT producto_id) clics
  4. FROM tracking_productos
  5.        FLOOR(visitdate/1800),
  6.        user_id
  7. HAVING clics > 0)t1 GROUP BY t1.user_id
De todas formas, sigo pensando que no te puede dar lo que buscas, que esto es otra cosa, pero tú decides.

Suerte

Última edición por jurena; 09/01/2013 a las 15:05
  #10 (permalink)  
Antiguo 09/01/2013, 15:16
Avatar de neodani  
Fecha de Ingreso: marzo-2007
Mensajes: 1.811
Antigüedad: 17 años, 1 mes
Puntos: 20
Respuesta: Contar clics únicos cada 30 minutos

Uhmm... tenias razón despues de numerosas pruebas pensaba que lo tenia, pero no... no me está contando como toca los tiempos. No por culpa de la subconsulta, sino por la consulta principal lástima.

Lo haré vía programación, la duda que tengo es si registrar cada clic o solo los que hayan transcurrido los 30 minutos desde la última vez que visitó ese usuario ese producto... pues si un usuario está en la pagina del producto y recarga la pagina varias veces me ha insertar una registro por cada recarga... saturando la bd...
  #11 (permalink)  
Antiguo 10/01/2013, 00:49
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Cáceres
Mensajes: 3.735
Antigüedad: 16 años
Puntos: 300
Respuesta: Contar clics únicos cada 30 minutos

Esta opción que planteas es más fácil de programar. Si no te interesan los demás clics para nada (lo digo por cuestión estadística), almacenas únicamente los clics que van a contarse. Comparas la última vez que guardaste un clic de ese cliente para ese producto con el momento actual e insertas en esa tabla solo cuando se haya producido media hora después de la última que tengas almacenada para el producto y ese usuario, o cuando no exista ningún clic de ese cliente o de ese cliente para ese producto. Lo demás será fácil: una consulta de agrupado por cliente, pero eso, no lo olvides, te hará perder información sobre los clics. Imagina que mañana decides cambiar el período a 15 minutos, o simplemente que quieres saber todos (su valor absoluto) los clicks sobre ese producto (no sé), o bien el día de la semana, hora minuto de más afluencia; pues bien, en ese caso ya no podrás recuperar los datos que necesitas.

Última edición por jurena; 10/01/2013 a las 09:21
  #12 (permalink)  
Antiguo 10/01/2013, 15:17
Avatar de neodani  
Fecha de Ingreso: marzo-2007
Mensajes: 1.811
Antigüedad: 17 años, 1 mes
Puntos: 20
Respuesta: Contar clics únicos cada 30 minutos

Cita:
Iniciado por jurena Ver Mensaje
Esta opción que planteas es más fácil de programar. Si no te interesan los demás clics para nada (lo digo por cuestión estadística), almacenas únicamente los clics que van a contarse. Comparas la última vez que guardaste un clic de ese cliente para ese producto con el momento actual e insertas en esa tabla solo cuando se haya producido media hora después de la última que tengas almacenada para el producto y ese usuario, o cuando no exista ningún clic de ese cliente o de ese cliente para ese producto. Lo demás será fácil: una consulta de agrupado por cliente, pero eso, no lo olvides, te hará perder información sobre los clics. Imagina que mañana decides cambiar el período a 15 minutos, o simplemente que quieres saber todos (su valor absoluto) los clicks sobre ese producto (no sé), o bien el día de la semana, hora minuto de más afluencia; pues bien, en ese caso ya no podrás recuperar los datos que necesitas.
Sí, eso sí, dejaré de tener información guardada en la BD. Pero es que sino, imagina un usuario que hace 1000 refresh de la pagina, o se monta un script para ello y me llena la BD de clics... tendría que tener algo para evitar esto y solo se me ocurre que no cuente cada clic, sino solo los clics válidos en este caso cada 30 min... aunque puedo ser menos severo y poner una restricción de 5 minutos¿? para cada clic del mismo producto y usuario, y luego aplicar el filtrado para contar los clics cada 30 min.

Etiquetas: cada, minutos, tabla
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 15:10.