Estou com dificuldade para converter procedimentos armazenados do SQL Server para Oracle para ter nosso produto compatível com ele.
Eu tenho consultas que retornam o registro mais recente de algumas tabelas, com base em um carimbo de data / hora:
Servidor SQL:
SELECT TOP 1 *
FROM RACEWAY_INPUT_LABO
ORDER BY t_stamp DESC
=> Isso me devolve o registro mais recente
Mas a Oracle:
SELECT *
FROM raceway_input_labo
WHERE rownum <= 1
ORDER BY t_stamp DESC
=> Isso retornará o registro mais antigo (provavelmente dependendo do índice), independentemente da ORDER BY
declaração!
Encapsulei a consulta Oracle desta maneira para corresponder aos meus requisitos:
SELECT *
FROM
(SELECT *
FROM raceway_input_labo
ORDER BY t_stamp DESC)
WHERE rownum <= 1
e funciona. Mas me parece um truque horrível, principalmente se eu tiver muitos registros nas tabelas envolvidas.
Qual a melhor maneira de alcançar isto ?
sql
oracle
sql-order-by
rownum
Larry
fonte
fonte
Respostas:
A
where
instrução é executada antes doorder by
. Portanto, sua consulta desejada está dizendo " pegue a primeira linha e ordene-a port_stamp
desc ". E não é isso que você pretende.O método de subconsulta é o método apropriado para fazer isso no Oracle.
Se você deseja uma versão que funcione nos dois servidores, você pode usar:
O externo
*
retornará "1" na última coluna. Você precisaria listar as colunas individualmente para evitar isso.fonte
Use em
ROW_NUMBER()
vez disso.ROWNUM
é uma pseudocoluna eROW_NUMBER()
é uma função. Você pode ler sobre a diferença entre eles e ver a diferença na saída das consultas abaixo:fonte
ROWNUM
pode ser mais rápido queROW_NUMBER()
isso, se um deve ou não usar um sobre o outro depende de vários fatores.Uma alternativa que eu sugeriria neste caso de uso é usar o MAX (t_stamp) para obter a última linha ... por exemplo
Minha preferência de padrão de codificação (talvez) - confiável, geralmente tem desempenho igual ou superior a tentar selecionar a primeira linha de uma lista classificada - também a intenção é mais explicitamente legível.
Espero que isto ajude ...
SQLer
fonte
Documentado alguns problemas de design com isso em um comentário acima. Em resumo, no Oracle, você precisa limitar os resultados manualmente quando tiver tabelas grandes e / ou tabelas com os mesmos nomes de coluna (e não desejar explicitamente digitar todas elas e renomeá-las todas). A solução fácil é descobrir seu ponto de interrupção e limitar isso na sua consulta. Ou você também pode fazer isso na consulta interna se não tiver a restrição de nomes de colunas conflitantes. Por exemplo
reduzirá substancialmente os resultados. Em seguida, você pode ORDER BY ou até fazer a consulta externa para limitar as linhas.
Além disso, acho que o TOAD tem um recurso para limitar linhas; mas não sei se isso limita a consulta real no Oracle. Não tenho certeza.
fonte