Limite una consulta MySQL a un número par de resultados
Pregunta
Tengo un código PHP que necesito para devolver un número par de resultados de una base de datos MySQL. Estoy usando la extensión mysqli para ejecutar mi consulta.
Mi código es aproximadamente esto en este momento:
//assume we already have a database connection
$query = "SELECT id
FROM movies
WHERE publish = 1
AND showimage = 1
ORDER BY date DESC
LIMIT 6";
$result = $connection->query($query);
while ($row = $result->fetch_assoc()) {
//do some stuff
}
Como puede ver, estoy limitando la consulta a 6 filas, pero en algunas condiciones, se devolverán menos. Si solo se devuelven 3 filas, quiero tirar la última fila y solo mantener 2.
¿Cómo puedo hacer esto en la consulta MySQL o en MySQLi?
Solución
Me imagino algo como esto:
// row counter
$counter = 1;
// loop through each row
while($row = $result->fetch_assoc()) {
// If there is more than one row remaining
// OR if the current row can be divided by two
if (($result->num_rows - $counter) > 1 || ($counter % 2)) {
// result code for even rows
$counter++;
} else {
// break out of the loop
break;
}
}
Otros consejos
Probablemente haría esto en PHP, en lugar de SQL. En el bucle while
, mantenga un contador y, cuando salga del bucle, verifique si el contador. Si es extraño, deseche los resultados de la última iteración.
Otra opción es solicitar un COUNT
y modificar la consulta de acuerdo con el resultado:
SELECT COUNT(*) FROM movies WHERE publish = 1 AND showimage = 1
No soy una persona PHP (han pasado años desde que lo vi) pero ...
Ross lo menciona pero quieres usarlo
$result->num_rows
de alguna manera dentro de su ciclo que procesa los resultados para mantener un número par de filas.
$ maxResults = $ result- > num_rows; if (($ maxResults% 2) = 1) $ maxResults--;
Cuando el contador es igual a $ maxResults, salga del ciclo.
Mi respuesta es solo mysql, aunque probablemente no sea la mejor, pero tal vez sea genial. :-)
SELECT size INTO @count FROM (SELECT COUNT(*) as size FROM (SELECT * FROM table LIMIT 6) l) t;
SET @count = @count - (@count % 2);
PREPARE stmt_limit FROM 'SELECT * FROM table LIMIT ?';
EXECUTE stmt_limit USING @count;
DEALLOCATE PREPARE stmt_limit;
Pasos:
- En la primera declaración puse cuántos resultados realmente obtuviste en la variable @count
- En la segunda declaración, decremento la variable con una si es desigual
- Prepare una declaración con su consulta y marcador de posición para el límite
- Ejecuta al bebé
- Deallocate, no sé si esto es necesario
Pero quién sabe, esto es quizás más rápido que las soluciones php ...
La forma más sencilla sería simplemente tomar las filas de dos en dos:
while($row1 = $result->fetch_assoc() && $row2 = $result->fetch_assoc()) {
do_something_with($row1);
do_something_with($row2);
}
(No es una persona PHP, pero carga la sintaxis de las otras respuestas ...)
Sharkey,
Su solución funcionará perfectamente pero necesita modificar un poco la sintaxis. Ver abajo.
while(($row1 = $result->fetch_assoc()) && ($row2 = $result->fetch_assoc()))
{
do_something_with($row1);
do_something_with($row2);
}
En la otra dirección, su segunda fila cancelará la primera fila y no mostrará la primera. Ahora mostrará ambos resultados. Buena solución simple, por cierto.