Hola! Me alegro de ver que te esforzaste en intentar algo, con gusto te respondere.
Primero que nada, el algoritmo esta bastante bien planteado solo tiene unas pequeñas falencias relacionadas con las preguntas que hiciste luego. Te voy a proponer otra forma de implemntarlo, solo con MySQL que te sera mas eficiente y facil de inplementar y mantener.
Para poblar la base de datos de prueba use el siguiente codigo (Para probar estas cosas hacen falta unos miles de registros, con solo 3 no se apreciara mucho):
Código PHP:
Ver original<?php
$fecha_desde = "2014-07-01 00:00:00";
$fecha_hasta = date("Y-m-d H:i:s"); $palabras_hashtags = array( 'photooftheday'
,'love'
,'igers'
,'cute'
,'me'
,'picoftheday'
,'sky'
,'bestoftheday'
,'girl'
,'igdaily'
,'beautiful'
,'food'
,'dog'
,'nature');
for($fecha=$fecha_desde; $fecha<=$fecha_hasta; $fecha=date("Y-m-d H:i:s", strtotime($fecha ." +30 second"))) {
mysqli_query($mysqli, "INSERT INTO `pruebas`.`publicaciones` (`fecha_publicacion`, `hashtag`) VALUES ('$fecha', '".($palabras_hashtags[rand(0, count($palabras_hashtags)-1)])."');") or
die("Error en consulta."); }
Luego de casi 3 minutos de ejecucion, la tabla quedo poblada con 1 hashtag cada 30 segundos (~83,297 registros)
El algoritmo que te propongo es este:
Código PHP:
Ver original/*
* Cantidad de dias que tendras en cuenta en el ranking.
* Los dias se cuentan de la fecha actual, hacia atras.
* En este caso son 7, es decir, la ultima semana.
*/
$reporte_ultimos_dias = 7;
/*
* Cantidad de minutos de los sub-intervalos de la puntuacion.
* Esto es con que frecuencia consideras que una aparicion de hashtag vale mas que otra.
* En este caso son 5, es decir, los que esten en los mismos 5 minutos, tendran el mismo indice de puntuacion.
*/
$lapso_de_intervalo = 5;
$sql = mysqli_query($mysqli, "SELECT info.hashtag, SUM(info.cantidad) menciones, ( (CEIL( ( TIMESTAMPDIFF ( MINUTE, DATE_SUB(NOW(), INTERVAL $reporte_ultimos_dias DAY),
NOW()
) / $lapso_de_intervalo)
) / info.intervalo_actual) * info.cantidad) puntuacion
FROM (
SELECT
hashtag,
CEIL( ( TIMESTAMPDIFF( MINUTE,
DATE_SUB(NOW(), INTERVAL $reporte_ultimos_dias DAY),
fecha_publicacion
) / $lapso_de_intervalo)
) intervalo_actual,
COUNT(DISTINCT id) cantidad
FROM publicaciones
WHERE ( fecha_publicacion >= DATE_SUB(NOW(), INTERVAL $reporte_ultimos_dias DAY) )
GROUP BY intervalo_actual, hashtag
HAVING intervalo_actual > 0
) info
GROUP BY info.hashtag
echo("<table>
<tr>
<th colspan=\"3\">Tendencias de los ultimos $reporte_ultimos_dias dias</th>
</tr>
<tr>
<th>#Hashtag</th>
<th>Menciones</th>
<th>Popularidad</th>
</tr>");
echo("<tr><td>#".$hashtag["hashtag"]."</td><td>".$hashtag["menciones"]."</td><td>".$hashtag["puntuacion"]."<td></tr>");
echo("</table>");
Para mis datos obtube esto:
Tendencias de los ultimos 7 dias
#Hashtag Menciones Popularidad
#bestoftheday 1453 4032.0000
#sky 1465 4032.0000
#photooftheday 1455 3024.0000
#beautiful 1410 2016.0000
#cute 1444 2016.0000
#love 1456 2016.0000
#picoftheday 1419 2016.0000
#girl 1434 2016.0000
#me 1444 2016.0000
#igers 1457 1344.0000
#food 1422 672.0000
#nature 1395 672.0000
#igdaily 1410 672.0000
#dog 1443 504.0000
Como puedes observar, la cantidad de menciones no es determinante, es importante que se lo mencione mucho, pero tambien es importante que se lo halla mencionado recientemente.
No es lo mismo lo mas mencionado que lo que esta de moda, puedes comparar esto con las visitas de un video de youtube, el video con mas visitas NO tiene porque ser el mas visitado, el de mas visitas es que fue visto mas veces, no importa cuando, el mas visitado es el que mas gente esta viendo ultimamente.
Seria cuestion de que ajustes los dos parametros para afinar el resultado tanto como quieras.
Cita: ¿Qué diferencia hay entre $inicio y $intervalo? ¿Qué significa $cant_intervalos?
La diferencia esta explicada en los comentarios del codigo que te acabo de pasar, les puse unos nombres mas claros a cada uno, la cantidad de intervalos es un valor calculado, no es un valor que debas porner tu, sino que se calcula solo en funcion de los dos valores anteriores.