Limitar uma consulta MySQL para um número par de resultados
Pergunta
Eu tenho um pouco de código PHP que eu preciso para retornar um número par de resultados de um banco de dados MySQL. Eu estou usando a extensão mysqli para executar minha consulta.
Meu código é aproximadamente isso no 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 você pode ver, eu estou limitando a consulta a 6 linhas, mas em algumas condições, menos será devolvido. Se apenas 3 linhas são retornadas, quero jogar fora a última linha e manter apenas 2.
Como posso fazer isso na consulta MySQL ou MySQLi?
Solução
Eu imagino algo como isto:
// 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;
}
}
Outras dicas
Eu provavelmente faria isso em PHP, em vez de SQL. No while
-loop, manter um balcão, e quando você sair do loop, verifique se o contador. Se é ímpar, jogar fora os resultados da última iteração.
Outra opção é pedir um COUNT
e alterar a consulta de acordo com o resultado:
SELECT COUNT(*) FROM movies WHERE publish = 1 AND showimage = 1
Eu não sou uma pessoa PHP (sua sido anos desde que eu olhei para ele), mas ....
Ross menciona-lo, mas você quer usar
$result->num_rows
de alguma maneira dentro de seu loop que processa os resultados para manter um número par de linhas.
$ maxResults = $ result-> num_rows; if (($ maxResults% 2) = 1) $ maxResults -;
Quando contador é igual a $ maxResults, sair do loop.
A minha resposta é mysql única, embora provavelmente não o melhor, mas talvez bem legal. : -)
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;
Passos:
- Na primeira instrução i colocar quantos resultados você realmente tem na variável @count
- Na segunda instrução i diminuir a variável com um se é desigual
- Preparar o documento com sua consulta e espaço reservado para o limite
- Execute o bebê
- Desalocar, não sei se isso é necessário
Mas quem sabe, este é talvez mais rápido, então a soluções php ...
A maneira mais simples seria a de simplesmente pegar as linhas dois de cada vez:
while($row1 = $result->fetch_assoc() && $row2 = $result->fetch_assoc()) {
do_something_with($row1);
do_something_with($row2);
}
(Não uma pessoa PHP, mas carga-culting a sintaxe das outras respostas ...)
Sharkey,
A sua solução irá funcionar perfeitamente, mas é necessário modificar a sintaxe um pouco. Veja abaixo.
while(($row1 = $result->fetch_assoc()) && ($row2 = $result->fetch_assoc()))
{
do_something_with($row1);
do_something_with($row2);
}
A outra maneira a sua segunda linha irá cancelar a primeira linha e não irá mostrar o primeiro. Agora ele irá exibir ambos os resultados. solução simples agradável, BTW.