Existe uma maneira de fazer uma Oracle
consulta se comportar como se contenha uma MySQL limit
cláusula?
Em MySQL
, eu posso fazer isso:
select *
from sometable
order by name
limit 20,10
para obter as linhas 21 a 30 (pule as 20 primeiras, dê as 10 seguintes). As linhas são selecionadas após o order by
, então ele realmente começa com o vigésimo nome em ordem alfabética.
Em Oracle
, a única coisa que as pessoas mencionam é a rownum
pseudo-coluna, mas ela é avaliada antes order by
, o que significa isso:
select *
from sometable
where rownum <= 10
order by name
retornará um conjunto aleatório de dez linhas ordenadas por nome, que geralmente não é o que eu quero. Também não permite especificar um deslocamento.
sql
oracle
pagination
sql-limit
Mathieu Longtin
fonte
fonte
ORDER BY
. Esse é o objetivo de pedir primeiro. Se os dados subjacentes mudarem e seu conjunto de resultados mudar por causa disso, por que não mostrar ao usuário os resultados atualizados em vez de informações desatualizadas? Além disso, a gestão do estado é uma praga a ser evitada o máximo possível. É uma fonte constante de complicações e bugs; é por isso que o funcional está ficando tão popular. E quando você saberia expirar todo o conjunto de resultados na memória? Na web, você não tem como saber quando o usuário sai.Respostas:
A partir da Oracle 12c R1 (12,1), não é uma linha limitar a cláusula . Ele não usa
LIMIT
sintaxe familiar , mas pode fazer o trabalho melhor com mais opções. Você pode encontrar a sintaxe completa aqui . (Leia também mais sobre como isso funciona internamente no Oracle nesta resposta ).Para responder à pergunta original, aqui está a consulta:
(Para versões anteriores do Oracle, consulte outras respostas nesta pergunta)
Exemplos:
Os exemplos a seguir foram citados na página vinculada , na esperança de impedir a podridão do link.
Configuração
O que há na mesa?
Obter primeiras
N
linhasObter primeiras
N
linhas, seN
a linha tiver vínculos, obter todas as linhas vinculadasx
% Superior de linhasUsando um deslocamento, muito útil para paginação
Você pode combinar o deslocamento com porcentagens
fonte
OFFSET FETCH
sintaxe é um açúcar sintático. DetalhesVocê pode usar uma subconsulta para isso como
Consulte também o tópico On ROWNUM e limite de resultados no Oracle / AskTom para obter mais informações.
Atualização : para limitar o resultado com limites inferior e superior, as coisas ficam um pouco mais inchadas com
(Copiado do artigo AskTom especificado)
Atualização 2 : A partir do Oracle 12c (12.1), há uma sintaxe disponível para limitar linhas ou iniciar com compensações.
Veja esta resposta para mais exemplos. Obrigado a Krumia pela dica.
fonte
Fiz alguns testes de desempenho para as seguintes abordagens:
Asktom
Analítico
Alternativa curta
Resultados
A tabela tinha 10 milhões de registros, a classificação estava em uma linha de data e hora não indexada:
A seleção das 10 primeiras linhas levou:
Selecionando linhas entre 100.000 e 100.010:
Selecionando linhas entre 9.000.000 e 9.000.010:
fonte
BETWEEN
é apenas um atalho para>= AND <=
( stackoverflow.com/questions/4809083/between-clause-versus-and )offset
sintaxe possui o mesmo plano e desempenho da abordagem analítica.Uma solução analítica com apenas uma consulta aninhada:
Rank()
pode ser substituído,Row_Number()
mas pode retornar mais registros do que o esperado, se houver valores duplicados para o nome.fonte
rank()
, também vale a pena notar odense_rank()
que pode ser mais útil para o controle de saída, pois o último não "pula" os números, enquanto querank()
pode. De qualquer forma, esta perguntarow_number()
é mais adequada. Um outro não é que esta técnica é aplicável a qualquer banco de dados que suporte as funções mencionadas.No Oracle 12c (consulte a cláusula de limitação de linha na referência SQL ):
fonte
LIMIT
SQL: 2008, eles tiveram que retirar uma folha do livro da Microsoft e quebrar o padrão.LIMIT ... OFFSET
LIMIT n, m
(Veja minha resposta). Então, novamente, a Oracle deveria ter implementadoLIMIT n, m
como açúcar sintático, como é equivalente aOFFSET n ROWS FETCH NEXT m ROWS ONLY
.As consultas de paginação com pedidos são realmente complicadas no Oracle.
O Oracle fornece uma pseudocoluna ROWNUM que retorna um número indicando a ordem na qual o banco de dados seleciona a linha de uma tabela ou conjunto de visualizações unidas.
ROWNUM é uma pseudocoluna que coloca muitas pessoas em problemas. Um valor ROWNUM não é atribuído permanentemente a uma linha (esse é um mal-entendido comum). Pode ser confuso quando um valor ROWNUM é realmente atribuído. Um valor ROWNUM é atribuído a uma linha depois de passar os predicados de filtro da consulta, mas antes da agregação ou classificação da consulta .
Além disso, um valor ROWNUM é incrementado somente depois de ser atribuído.
É por isso que a consulta a seguir não retorna linhas:
A primeira linha do resultado da consulta não passa o predicado ROWNUM> 1; portanto, o ROWNUM não aumenta para 2. Por esse motivo, nenhum valor de ROWNUM fica maior que 1, consequentemente, a consulta não retorna linhas.
A consulta definida corretamente deve ficar assim:
Saiba mais sobre consultas de paginação em meus artigos no blog Vertabelo :
fonte
Padrão SQL
Como expliquei neste artigo , o SQL: 2008 Standard fornece a seguinte sintaxe para limitar o conjunto de resultados do SQL:
Oracle 11g e versões anteriores
Antes da versão 12c, para buscar os registros Top-N, era necessário usar uma tabela derivada e a pseudocoluna ROWNUM:
fonte
Menos instruções SELECT. Além disso, consome menos desempenho. Créditos para: [email protected]
fonte
Como uma extensão da resposta aceita, a Oracle usa internamente
ROW_NUMBER/RANK
funções.OFFSET FETCH
sintaxe é um açúcar de sintaxe.Isso pode ser observado usando o
DBMS_UTILITY.EXPAND_SQL_TEXT
procedimento:Preparando a amostra:
Inquerir:
é regular:
db <> demo de violino
Buscando texto SQL expandido:
WITH TIES
é expandido comoRANK
:e deslocamento:
fonte
Se você não estiver no Oracle 12C, poderá usar a consulta TOP N como abaixo.
Você pode até mover isso da cláusula com a cláusula da seguinte maneira
Aqui, na verdade, estamos criando uma exibição em linha e renomeando rownum como rnum. Você pode usar rnum na consulta principal como critério de filtro.
fonte
ORDER BY
e orownum
separadamente. Basicamente, criei uma subconsulta que continha aORDER BY
cláusula .rownum
deveria estar fora de uma subconsulta.Comecei a me preparar para o exame Oracle 1z0-047, validado contra 12c. Ao me preparar para isso, deparei-me com um aprimoramento 12c conhecido como 'FETCH FIRST'. Ele permite que você busque linhas / limite linhas conforme sua conveniência. Várias opções estão disponíveis com ele
Exemplo:
fonte
maior que os valores descobrem
menos que os valores descobrem
fonte
ROW_NUMBER()
solução baseada já havia sido publicado por Leigh Riffel. Além disso, há erros de sintaxe no código mostrado.Para cada linha retornada por uma consulta, a pseudocoluna ROWNUM retorna um número indicando a ordem na qual o Oracle seleciona a linha de uma tabela ou conjunto de linhas unidas. A primeira linha selecionada tem um ROWNUM de 1, a segunda tem 2 e assim por diante.
Eu implementei isso no
oracle
servidor11.2.0.1.0
fonte
No caso do SQL-Developer, ele busca automaticamente apenas as primeiras 50 linhas. E se rolarmos para baixo, ele buscará outras 50 linhas e assim por diante!
Portanto, não precisamos definir, no caso da ferramenta sql-developer!
fonte
No oracle
VAL
5 linhas selecionadas.
SQL>
fonte
(não testado) algo assim pode fazer o trabalho
Há também a classificação da função analítica, que você pode usar para ordenar.
fonte
O mesmo que acima com correções. Funciona, mas definitivamente não é bonito.
Honestamente, é melhor usar as respostas acima.
fonte