paso - PhP/MySQL: cómo cambiar dinámicamente mi base de datos(grande y siempre cambiante)
pagina web con base de datos mysql (2)
Guión
Tengo una base de datos MySQL con 10.000 filas. Configuración de la base de datos:
ID UniqueKey Name Url Score ItemValue
1 5Zvr3 Google google.com 13 X
2 46cfG Radio radio.com -20 X
3 2fg64 Yahoo yahoo.com 5 X
.... etc etc etc
Como puede ver, cada elemento tiene una puntuación . La puntuación cambia constantemente. Google puede tener un puntaje de 13 ahora, pero mañana puede ser 80, o -50.
Lo que quiero:
Quiero crear un sistema que cree una jerarquía en mi base de datos actual, en función del puntaje de los elementos. En este momento, estoy pensando en los rangos de percentiles , lo que significa que los artículos de mayor puntaje estarán cerca del 100%, y los puntos con las puntuaciones más bajas estarán cerca del 0%. Para esto creé un código que intentará lograr lo que se muestra aquí: http://www.psychstat.missouristate.edu/introbook/sbk14m.htm
Este es mi código:
$sql = "SELECT * FROM database order by Score";
$result = $conn->query($sql);
$count = 0;
while ($row = $result->fetch_assoc()) {
$woow = $row[''Score''];
$sql = "SELECT * FROM database WHERE Score = $woow";
$resultnew = $conn->query($sql);
$somanythesame = $resultnew->num_rows;
$itemPercentile = ( ($count/$result->num_rows + 0.5*$somanythesame/$result->num_rows) * 100 );
$rowID = $row[''ID''];
$sql2 = "UPDATE database SET itemValue = $itemPercentile WHERE ID = $rowID";
$conn->query($sql2);
$count++;
}
Esto funciona, pero para un problema no: Hay muchos elementos en mi base de datos, muchos con el mismo puntaje . Para ilustrar mi problema, aquí hay una base de datos de 10 filas muy simple con solo los puntajes:
Puntuaciones
-10
0
0
0
10
20
20
30
40
50
El problema con mi código es que no da el mismo percentil para los artículos con el mismo puntaje , porque tiene en cuenta todas las filas anteriores para el cálculo, incluidas las que tienen el mismo puntaje.
Entonces, para el 2º, 3º y 4º elemento con una Score of 0
, debería ser así: (1/10 + 0.5*1/10) * 100
. El problema es que para el 3er artículo lo hará (2/10 + 0.5*1/10) * 100
y el 4 ° elemento lo hará (3/10 + 0.5*1/10) * 100
.
Luego, para el 5º artículo con un puntaje de 10, debería hacerlo (4/10 + 0.5*1/10) * 100
. Esto está yendo bien; solo no para los artículos con el mismo puntaje
No estoy seguro si lo expliqué bien, me resulta difícil expresar mi problema con las palabras correctas. ¡Si tiene alguna pregunta, hágamelo saber! Gracias por tu tiempo :)
Necesita mantener una variable de "conteo idéntico" ( $icount
) que rastrea la cantidad de elementos con un puntaje idéntico y un "puntaje actual" ( $score
) que rastrea el puntaje actual.
$icount = 0;
$score = null;
Incremente $icount
lugar de $count
cuando $woow == $score
(cheque de valor idéntico). De lo contrario, agréguelo a $count
e incremente, y luego restablezca el valor de $icount
a 0.
if ($woow == $score) {
$icount++;
} else {
$count += $icount + 1;
$icount = 0;
}
Finalmente, configure su valor de $score
en el último $woow
para probar en la próxima iteración del ciclo:
$score = $woow;
Esto permitirá que los artículos con el mismo puntaje tengan el mismo $count
, mientras que incrementa un $icount
adicional cuando se encuentra un nuevo $score
.
Tu código final se verá así:
$sql = "SELECT * FROM database order by Score";
$result = $conn->query($sql);
$count = 0;
$icount = 0;
$score = null;
while ($row = $result->fetch_assoc()) {
$woow = $row[''Score''];
$sql = "SELECT * FROM database WHERE Score = $woow";
$resultnew = $conn->query($sql);
$somanythesame = $resultnew->num_rows;
$itemPercentile = ( ($count/$result->num_rows + 0.5*$somanythesame/$result->num_rows) * 100 );
$rowID = $row[''ID''];
$sql2 = "UPDATE database SET itemValue = $itemPercentile WHERE ID = $rowID";
$conn->query($sql2);
if ($woow == $score) {
$icount++;
} else {
$count += $icount + 1;
$icount = 0;
}
$score = $woow;
}
Puede cambiar la consulta de $ sql:
$sql = "SELECT *,count(*) FROM database group by Score order by Score";
En este caso, obtiene puntaje con conteos y no necesita más selección en el ciclo while.
Incluso puede seleccionar Percentile en la consulta MySQL:
Select t2.* , @fb as N , ((t2.fb1 + 0.5 * t2.fw)/@fb*100) as percentile from (
Select t1.* , (@fb := @fb + t1.fw) as fb1 from (
Select score,count(*) as fw From tablename group by score order by score ASC
) as t1
) as t2
Creo que esta consulta devuelve la mayoría de las columnas que puede necesitar para verificar los resultados.