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

Paginacion de noticias PHP/MySQL con ranking de registros

Estas en el tema de Paginacion de noticias PHP/MySQL con ranking de registros en el foro de Mysql en Foros del Web. Hola! soy nuevo por acá y aunque en ocaciones el foro me ayudó a descubrir consultas o dudas sobre ciertos detalles de php o mysql, ...
  #1 (permalink)  
Antiguo 03/11/2009, 21:22
 
Fecha de Ingreso: noviembre-2009
Mensajes: 5
Antigüedad: 14 años, 5 meses
Puntos: 0
Paginacion de noticias PHP/MySQL con ranking de registros

Hola! soy nuevo por acá y aunque en ocaciones el foro me ayudó a descubrir consultas o dudas sobre ciertos detalles de php o mysql, nunca había posteado porque no me había topado con ningún gran dilema... hasta hoy!

No se cuan avanzado o dificil será mi planteo, pero bueno, planteo la situación y a ver si alguno me ayuda con este embrollo!

Mis dilemas serían 2, aunque creo que podrían llegar a tener misma solución.

En una base de datos MySQL tengo determinada cantidad de registros (mas de 2000). Hasta ahora nada complejo.
Dichos registros son noticias que tienen un determinado orden para mostrarse, es decir, si bien todas las noticias tienen un campo ID, no son ordenadas por este valor, sino que cada una tiene grado de importancia y una posición particular (Imaginen un portal de noticias donde haya un cuadro principal que se muestran las noticias mas "destacadas" -posicion- y que a su vez esas noticias tienen un orden de acuerdo al interes del autor de la noticia de cual mostrar primera o segunda -importancia-). Esto lo aclaro principalmente para dejar en claro que la ID de los registros es usada solo para llamar a determinada noticia, pero nada tiene que ver con su orden de ingreso (La última noticia ingresada NO TIENE PORQUE ser la más importante o la que se quiera mostrar primero).
Hasta acá, nuevamente, viene todo en orden.

En el momento que hago la paginación, es el mismo orden sistemático que lo antes explicado, dicha paginación debe ordenarlas por posicion (de la 1 a la 5, donde la posicion 1 es mas importante y la 5 menos), por importancia (a,b,o c, mismo sentido que lo anterior) y al mismo tiempo por fecha y hora ingresadas (en el caso que dos noticias tengan misma importancia y posición, la mas nueva va primero... hablando en orden descendente). La paginación sería mas o menos con la siguiente estructura:

<< Primera Noticia | < Noticia Anterior | 1 - 2 - 3 - 4 - 5 | Siguiente Noticia > | Ultima Noticia >>

Y acá es donde empiezan a insultarse mis propias neuronas entre si.

Para obtener el link a la primera noticia no es tan grave: Hago una consulta SELECT que me traiga la primera noticia bajo un orden determinado y termino la consulta ahi mismo, sería algo como:

SELECT * FROM `noticias` ORDER BY `posicion`,`importancia`,`fecha_y_hora` DESC LIMIT 1

Al tener un campo que guarda la fecha y la hora, y al ser que los valores mínimos (por ejemplo, 1 - a) de "importancia" y "posicion" son los que me interesan primero, me resulta sencillo obtener el primer registro (o noticia) mas importante sabiendo tambien la ultima fecha y hora de ingreso. Luego el valor de la ID lo uso para crear el link.

El problema es con "ULTIMA NOTICIA", ya que si bien podria hacer un WHILE de la misma consulta de arriba (quitando el LIMIT), el loop terminaría dándome el último registro con su correspondiente ID, pero el problema serían los recursos, ya que si ya tengo 2000 registros (y cada vez son más), esa consulta podría ser terriblemente lenta para obtener esa última noticia.
En definitiva lo que pensé es la posibilidad que con MySQL se le pueda poner, un numero de "posicion" por asi decirlo, pudiendo obtener la última posición de acuerdo al ORDER BY que le indico, más allá de la ID que tengan cada una. Y por supuesto, obtener la ID de esa úlima posición.

Y ahora lo mas complejo, a mi entender (que no niego que sea escaso! :P), sería ese mismo posicionamiento en caso que no me encuentre ni en la primera ni en la ultima posición, ya que como indiqué arriba en la estructira de los links de paginación, tengo los números (1 - 2 - 3 - 4 - 5) que me indican el número de noticia (repito, orden de acuerdo al ORDER BY, no a la ID) y que si estoy en la noticia 3, debo saber cuales son las noticias 1, 2, 4 y 5 también, ya que debo generar un link que me lleve hasta ellas.

Nuevamente el problema es el mismo, los recursos del server, ya que estuve realizando pruebas y logro conseguir la posición con una funcion PHP, pero no logro como hacer para no tener que recorrer absolutamente toda la base para descubrir las ID de cada una para generar los links.
Asi sería como hice las pruebas:

function nums($id_nota) { // inicio funcion
$cuenta = 1;
$sql = mysql_query("SELECT * FROM `noticias` ORDER BY `posicion`,`importancia`,`fecha_y_hora` DESC");
while ($row = mysql_fetch_assoc($sql)) {
$idnota[$cuenta] = $row[id];
$cuenta++;
}

// Aca yo se que tengo mi primer error, ya que estoy armando un "ranking" pero estoy recorriendo toda la base (la variable $id viene de un llamado a funcion asi: nums($id); a la cual le envío la id de noticia que estoy, para saber (o intentar hacerlo) que posición tiene ESA ID y que ID's son las dos anteriores y las dos siguientes).
Luego hice un FOR mas o menos asi:

for ($count=1;$count<=count($idnota);$count++) {
if ($idnota[$count] == $id_nota) {
$count2 = $count - 2;
$count3 = $count - 1;
$count4 = $count + 1;
$count5 = $count + 2;
}
}

// A este FOR le faltan lineas que no vienen al caso para determinar si estoy en la noticia 1,2, 3 o en la que sea, donde en ese momento (si estoy en la noticia 4, por ejemplo), en lugar de querer saber las dos anteriores o las dos siguientes, serían las 3 anteriores y solo una siguiente (se entiende?)

$paginacion = '<a href="?id='.$idnota[$count2].'">1</a> | <a href="?id='.$idnota[$count3].'">2</a> | <strong>3</strong> | <a href="?id='.$idnota[$count4].'">4</a> | <a href="?id='.$idnota[$count5].'">5</a>';

// Acá les muestro la variable que devuelve el codigo html para armar esa numeración. Acá pueden ver porque resto y sumo valores a la variable "$count" para moverle la posicion a ese puntero y asi traer los valores de las ID guardadas en el arreglo "$idnota", y solo pongo en negrita el numero de la noticia que se esta viendo (ya que este ejemplo que presento, es en el caso que se vea la noticia 3... que en realidad puede ser la 546... pero bueno, creo que resolviendolo con esto ya esta solucionado el resto)

return $paginacion;

} // fin funcion


Puse todo esto para poder explicar a grandes rasgos el funcionamiento y como habia empezado a hacerlo, y es mas, esto FUNCIONA, el gran problema es el consumo de recursos del server, ya que como ven en el WHILE, recorro toda la base para darles las "posiciones de ranking" a las noticias y de ahi determinar cual posición estoy viendo y cuales debo guardar para armar los links.

Cerrando todo esto (wow, creo que por no haber posteado me guarde todo para esto!), mi consulta apunta a alguna forma, sentencia o funcion MySQL que me ayude con el tema de los recursos respetando el orden que le doy a la consulta sql, para armar esa especie de "ranking" que necesito para poder armar la paginación de las noticias. O tal vez alguna concatenación de querys, que no se me está ocurriendo.

Por favor, si lo que acabo de explicar es inentendible, aclarenmeló y trataré de explicarlo mejor, a ver si puedo conseguir alguna alma caritativa que me de una mano con esto o simplemente alguien con ganas de asumir el desafio y dolor de cabeza que esto representó para mi! :(

Desde ya, muchisimas gracias!!

Última edición por Vehemente; 03/11/2009 a las 21:50
  #2 (permalink)  
Antiguo 04/11/2009, 15:32
Avatar de mortiprogramador
Colaborador
 
Fecha de Ingreso: septiembre-2009
Ubicación: mortuoria
Mensajes: 3.805
Antigüedad: 14 años, 7 meses
Puntos: 214
Respuesta: Paginacion de noticias PHP/MySQL con ranking de registros

Hola
Bueno, no se si has probado todo el "poder" del limit

tu tienes

SELECT * FROM `noticias` ORDER BY `posicion`,`importancia`,`fecha_y_hora` DESC LIMIT 1
lo que trae solo 1 dato y luego haces tus diligencias, porque no intentas con esto

SELECT * FROM `noticias` ORDER BY `posicion`,`importancia`,`fecha_y_hora` DESC LIMIT 0,5

asì pues, la consulta traera solo 5 registros que es lo que entiendo necesitas, y pues empieza desde la posiciòn 0, es decir, desde la primera coincidencia, si necesitaras por ej mostrar 6 noticias, entonces te recomendaria usar una variable que se incremente (y decremente) de a 1 para que solo se cambie el limit, asi

"SELECT * FROM `noticias` ORDER BY `posicion`,`importancia`,`fecha_y_hora` DESC LIMIT ".$var.",5"
y asi entonces, $var empezaria en 0 y mostraria las primeras 5, y luego al volverse $var = 1 entonces mostraria las noticias 2 a 5 y la noticia 6, sacando a la primera noticia, y para volver a verla, entonces $var = 0, espero no haberte enredado mas.... jajaj, bueno, intenta con eso a ver si te da alguna soluciòn
saludos
  #3 (permalink)  
Antiguo 06/11/2009, 14:56
 
Fecha de Ingreso: noviembre-2009
Mensajes: 5
Antigüedad: 14 años, 5 meses
Puntos: 0
Respuesta: Paginacion de noticias PHP/MySQL con ranking de registros

Cita:
Iniciado por mortiprogramador Ver Mensaje
Hola
Bueno, no se si has probado todo el "poder" del limit

tu tienes

SELECT * FROM `noticias` ORDER BY `posicion`,`importancia`,`fecha_y_hora` DESC LIMIT 1
lo que trae solo 1 dato y luego haces tus diligencias, porque no intentas con esto

SELECT * FROM `noticias` ORDER BY `posicion`,`importancia`,`fecha_y_hora` DESC LIMIT 0,5

asì pues, la consulta traera solo 5 registros que es lo que entiendo necesitas, y pues empieza desde la posiciòn 0, es decir, desde la primera coincidencia, si necesitaras por ej mostrar 6 noticias, entonces te recomendaria usar una variable que se incremente (y decremente) de a 1 para que solo se cambie el limit, asi

"SELECT * FROM `noticias` ORDER BY `posicion`,`importancia`,`fecha_y_hora` DESC LIMIT ".$var.",5"
y asi entonces, $var empezaria en 0 y mostraria las primeras 5, y luego al volverse $var = 1 entonces mostraria las noticias 2 a 5 y la noticia 6, sacando a la primera noticia, y para volver a verla, entonces $var = 0, espero no haberte enredado mas.... jajaj, bueno, intenta con eso a ver si te da alguna soluciòn
saludos
Hola mortiprogramador y gracias.

Lo que me decis estaría bien en caso que yo mostrara las noticias desde LA QUE VEO hacia las 5 siguientes (es decir, es muy util si estoy viendo menos de las 6 primeras noticias). Pero como está en el ejemplo en mi post anterior, la que se está viendo es (en el paginador por numeros) la del medio, por lo que debo obtener los 2 registros siguientes y los 2 anteriores. Si hago un limite determinado por una variable que se acrecienta en cada loop, como determino el valor de esa variable si estoy viendo la noticia 654 (por decir un numero) si justamente lo que necesito averiguar que esa noticia es la 654 sin recorrer toda la base.
De cualquier manera me hiciste notar que para obtener la ultima pagina era mas facil que como lo hacia, ya que previamente puedo obtener el numero TOTAL de registros bajo ciertos delimitadores y partiendo de ese numero, muestro la ultima noticia, sería así:

$sql1 = mysql_query("SELECT * FROM `noticias`");
$total = mysql_num_rows($sql1); // supongamos que me devuelve 2000
$total = $total-1; // le resto uno para en el siguiente query llevarlo DESDE el registro 1999 y mostrar 1 solo (el ultimo)

$sql = mysql_query("SELECT * FROM `noticias` ORDER BY posicion,importancia,fecha_y_hora DESC LIMIT $total,1");

Y con esa ultima sentencia ya se cual es el ultimo registro ordenado de la manera que quiero sin recorrer toda la tabla.
Acá te agradezco porque el uso de esa variable se me ocurrió debido a tu post, je.

Pero sigue siendo un tema el paginador de numeros...
Ahora... me pregunto:

¿HAY ALGUNA SENTENCIA SQL QUE ME PERMITA CONTAR LOS REGISTROS HASTA UN DETERMINADO REGISTRO QUE YO QUIERA?

Creo que podria ir por ahi la solución, si pudiera obtener la cuenta de registros hasta (...por ejemplo) la noticia con id 345 (que puede estar en la posición 100, de acuerdo al ORDER BY) entonces podria determinar a partir de ahi las siguientes o posteriores noticias con mas facilidad. El problema es que no se si realmente se puede hacer, o al menos no he leido nada al respecto en foros o en San Google.

Nuevamente gracias y saludos
  #4 (permalink)  
Antiguo 07/11/2009, 13:18
Avatar de mortiprogramador
Colaborador
 
Fecha de Ingreso: septiembre-2009
Ubicación: mortuoria
Mensajes: 3.805
Antigüedad: 14 años, 7 meses
Puntos: 214
Respuesta: Paginacion de noticias PHP/MySQL con ranking de registros

hola
uhm, bueno, pues se me ocurre entonces manejar
2 consultas con diferentes order (desc y asc) y que el limit para
ambas sea 2, pues necesitas las dos anteriores y las dos siguientes
que te parece eso? sera que se acomoda a lo que necesitas?

y bueno, lo que dices de obtener el total de registros hasta un determinado
registro seria con esto

select count(id) from tabla where id <= valor;

prueba y nos comentas

saludos
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 09:57.