¿Cómo calcular el rango de percentil para los totales de puntos en diferentes períodos de tiempo?

StackOverflow https://stackoverflow.com/questions/1007146

  •  06-07-2019
  •  | 
  •  

Pregunta

En un PHP & amp; Sitio web basado en CodeIgniter, los usuarios pueden ganar reputación por diversas acciones, a diferencia de Stack Overflow. Cada vez que se otorga reputación, se crea una nueva entrada en una tabla MySQL con el user_id , la acción que se recompensa y el valor de ese grupo de puntos (por ejemplo, 10 reputación). Al mismo tiempo, se actualiza un campo en una tabla users , reputación_total .

Dado que todo esto no tiene sentido sin un marco de referencia, quiero mostrar a los usuarios su rango de percentil entre todos los usuarios. Para la reputación total, eso parece bastante fácil. Digamos que mi user_id es 1138 . Simplemente cuente el número de usuarios en la tabla users con un reputación_total menor que el mío, cuente el número total de usuarios y divida para encontrar el porcentaje de usuarios con una reputación más baja que el mío. Ese será el rango percentil del usuario 1138, ¿verdad? ¡Fácil!

Pero también estoy mostrando totales de reputación en diferentes períodos de tiempo, por ejemplo, ganados en los últimos siete días, lo que implica consultar la tabla de reputación y sumar todos mis puntos ganados desde una fecha determinada. También me gustaría mostrar el rango de percentiles para los diferentes períodos de tiempo, por ejemplo, puedo ser el percentil 11 en general, pero el percentil 50 este mes y el percentil 97 hoy.

Parece que tendría que revisar y encontrar los totales de reputación de todos los usuarios para el lapso de tiempo determinado, y luego ver dónde pertenezco a ese grupo, ¿no? ¿No es terriblemente engorroso? ¿Cuál es la mejor manera de hacer esto?

Muchas gracias.

¿Fue útil?

Solución

Puedo pensar en algunas opciones fuera de mi cabeza aquí:

  1. Como mencionó, sume los puntos de reputación ganados durante el rango de tiempo y calcule los rangos de percentiles en función de eso.

  2. Realice un seguimiento de las actualizaciones de reputación_total a diario, de modo que tenga una tabla con user_id, fecha, reputación_total.

  3. Agregue algunas columnas nuevas a la tabla de usuarios (reputación_total, reputación_total_today, reputación_total_últimos 30 días, etc.) para cada rango de tiempo. También puede normalizar esto en una tabla separada (reputación_totals) para evitar que tenga que agregar una nueva columna para cada período de tiempo que desee rastrear.

La opción n. ° 1 es la más fácil, pero probablemente será más lenta si tiene muchas filas en su tabla de transacciones de reputación; no se escalará muy bien, especialmente si necesita calcularlas en tiempo real.

La opción # 2 requerirá más almacenamiento a lo largo del tiempo (una fila por usuario por día) pero probablemente sería significativamente más rápido que consultar la tabla de transacciones directamente.

La opción # 3 es menos flexible, pero probablemente sería la opción más rápida.

Ambas opciones 2 & amp; 3 probablemente requeriría un proceso por lotes para calcular los totales a diario, por lo que también es algo a considerar.

No creo que ninguna opción sea necesariamente la mejor, todas implican diferentes compensaciones de velocidad / espacio de almacenamiento / complejidad / flexibilidad. Lo que haga dependerá en última instancia de los requisitos para su aplicación, por supuesto.

Otros consejos

No veo por qué eso sería demasiado complejo. En general, todo lo que necesitaría es agregar a su cláusula WHERE una consulta que limite resultados como:

WHERE DatePosted between @StartOfRange and @EndOfRange
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top