Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Dexter Morgan

Exibir Registro

Recommended Posts

A solução é menos lógica, você deve utilizar um sub-select:

'SELECT 
   * 
FROM 
   TABELA
WHERE 
   id NOT IN (SELECT id FROM tabela LIMIT 5);'

Assim, você dirá que quer todos os itens da tabela, menos os 5 primeiros retornados no sub-select.

 

Você ainda pode, ou deve, ordenar as consultas pelo ID:

'SELECT 
   * 
FROM 
   TABELA
WHERE 
   id NOT IN (SELECT id FROM tabela ORDER BY id ASC LIMIT 5)
ORDER BY
   id ASC;'

Só lembrando que o limit deve ser o último item da query.

 

Como eu vi que você precisa do quinto em diante, é só alterar o LIMIT de 5 para 4.

 

'SELECT 
   * 
FROM 
   TABELA
WHERE 
   id NOT IN (SELECT id FROM tabela ORDER BY id ASC LIMIT 4)
ORDER BY
   id ASC;'

Compartilhar este post


Link para o post
Compartilhar em outros sites

Coloque um número gigante no limit:

DESC LIMIT 100000000000 OFFSET 4

 

Henrique assim deu certo o que eu queria, mas só mencionando, isso ficou gambiarra neh rsrs, mas funcionou e isso que importa :thumbsup:

Compartilhar este post


Link para o post
Compartilhar em outros sites

Por eu trabalhar mais com postgre e mssql, não conhecia dessa peculiaridade do MySQL. Entretanto, a solução não gambiarra (é gambiarra, mas não possui o problema de algum dia estourar o LIMIT), seria a seguinte:

'
SELECT 
   * 
FROM 
   tabela 
   LEFT JOIN (SELECT id FROM tabela LIMIT 4) AS a USING(id) 
WHERE 
   a.id IS NULL;'

O que acontece nesse código é o seguinte. Você compara os dados de uma tabela com os 4 primeiros dados da mesma tabela. Após, indica, que quer somente os dados que não foram retornados na segunda tabela.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Mas Gabriel, em termos de performance, a sua solução não é a ótima.

Essa gambiarra surge do próprio MySQL, pois ele não aceita números negativos nem NULL na cláusula LIMIT.

Pesquise pelo maior número inteiro suportado pelo MySQL e o utilize. Se o número de registros da tabela exceder isso, bom, aí você terá problemas bem mais sérios que essa query para se preocupar.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Caras, ontem me peguei confabulando a respeito desse tópico e cheguei à seguinte conclusão:

 

Porque raios a gente complica tanto a vida???

 

<?php

$conn = new PDO('mysql:host=localhost', 'root', 'root');
$stmt = $conn->prepare('show tables from information_schema');
$stmt->execute();
$data = $stmt->fetchAll(PDO::FETCH_ASSOC);

print_r(array_slice($data, 4));

Compartilhar este post


Link para o post
Compartilhar em outros sites

Como eu gosto da coisa na prática, e ter a certeza dos mitos x fatos, resolvi fazer uns testes. Possuo uma tabela em mysql com mais de 12 milhões de registros (12.444.556 para ser exato).

 

Primeira consulta

'SELECT 
   T.* 
FROM 
   tabela T
   LEFT JOIN (SELECT id FROM tabela LIMIT 4) AS a USING(id) 
WHERE 
   a.id IS NULL'

Retorno:

Mostrando de 0 - 12,444,552 (12,444,552 total, Consulta levou 0.032 segundos / Fetch levou 6.801 segundos)

Essa é a mensagem que vem do PHPMyAdmin, entretanto, está com valores retornados do MySQL Workbench

 

Segunda consulta:

SELECT 
   T.*
FROM 
   tabela T
LIMIT 15000000 OFFSET 4

 

Executei, fiquei sem memória na máquina e nenhuma query mais funcionou, nem reiniciando. Então, realizei os testes retornando 4 milhões de registros.

 

Colocarei as diferenças(query/fetch), em segundos, de cada teste. Utilizei o MySQL Workbench 5.2 CE para os testes.

JOIN TABLE    | LIMIT
0.032 / 8.532 | 0.016 / 8.096
0.016 / 8.157 | 0.000 / 7.748
0.016 / 8.096 | 0.016 / 7.652

Como não estava confiando nos resultados do MySQL Workbench, fui para o HeidiSQL 7.0. Ele retorna o tempo total, desde a query quanto o fetch.

Primeira consulta:

'SELECT 
   T.*
FROM 
   tabela T
   LEFT JOIN (SELECT id FROM tabela LIMIT 4) A on (T.id = A.id)
WHERE 
   A.id IS NULL
LIMIT 4000000;'

 

Segunda consulta

'SELECT 
   *
FROM 
   tabela T
LIMIT 4000000 OFFSET 4;'

 

Resultados

JOIN TABLE  | LIMIT
9,578       | 8,658
9,219       | 7,223
9,266       | 6,645
9,859       | 7,800
9,844       | 7,628 

É mais rápido utilizar limit e mais fácil de se escrever. Além disso, o LIMIT aumenta sua performance com a repetição, enquanto o JOIN se mantêm estável. Também deve-se levar o fato, ou não, da query com JOIN também utilizar LIMIT.

 

Entretanto, eu vi dois problema utilizando o limit, que são fatores que eu uso no dia-a-dia:

 

1º - utilizando o limit, não é possível realizar a paginação. Se paginar, mostra os primeiros 4 registros, se quiser paginar e utilizar limit ao mesmo tempo, parte-se para a LimitIteration. Com mais de mil registros, começa a pesar demais. O PHPMyAdmin utiliza o limit para a paginação. E utilizando a claúsula limit, ele não pagina.

 

2º - Não realiza a contagem de registros. Só retorna 0 linhas ou conjunto vazio.

 

Porque raios a gente complica tanto a vida???

Sou curioso em saber todas as possibilidades, não me prendo a somente uma. E porque as maiorias descobertas do mundo foram feitas através de grandes, e boas, complicações.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Como eu gosto da coisa na prática, e ter a certeza dos mitos x fatos, resolvi fazer uns testes. Possuo uma tabela em mysql com mais de 12 milhões de registros (12.444.556 para ser exato).

 

set @counter = 0; select t.id from (select @counter := @counter + 1 as row, id from tabela) as t where t.row > 4

 

Se o sistema de caching do MySQL for tão inteligente quanto penso, essa vai ser a consulta mais performática. Infelizmente, para ter uma comparação fiel, você precisará reeditar as consultas anteriores para receber apenas o ID, como fiz nessa.

 

Sou curioso em saber todas as possibilidades, não me prendo a somente uma. E porque as maiorias descobertas do mundo foram feitas através de grandes, e boas, complicações.

 

Perfeito. Até porque todas as soluções apresentadas eram totalmente SQL. Portáveis tanto para Postgre quanto Sqlite e ainda chuto um palpite do MSSql. Mas, sei lá, ando pensando de forma muito prática ultimamente. Foi a solução mais simples que me veio à cabeça. E penso ser também uma das mais leves.

 

Consegui outra! Ressaltando que estou testando apenas no MySQL

 

set @counter = 0; select *, (@counter := @counter + 1) > 4 as 'rownum' from tabela having rownum;

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.