Implementações de banco de dados de ORDER BY em uma subconsulta

10

Estou usando um aplicativo (MapServer - http://mapserver.org/ ) que agrupa instruções SQL, para que a instrução ORDER BY esteja na consulta interna. Por exemplo

SELECT * FROM (
        SELECT ID, GEOM, Name
        FROM t
        ORDER BY Name
        ) as tbl

O aplicativo possui muitos drivers de banco de dados diferentes. Eu uso principalmente o driver do MS SQL Server e o SQL Server 2008. Isso gera um erro se um ORDER BY for encontrado em uma subconsulta.

No MS Docs (embora isso seja para o SQL Server 2000, ainda parece se aplicar):

Quando você usa uma cláusula ORDER BY em uma exibição, uma função embutida, uma tabela derivada ou uma subconsulta, ela não garante a saída ordenada. Em vez disso, a cláusula ORDER BY é usada apenas para garantir que o conjunto de resultados gerado pelo operador Top tenha uma composição consistente. A cláusula ORDER BY garante apenas um conjunto de resultados ordenados quando é especificado na instrução SELECT mais externa.

No entanto, o mesmo tipo de consulta, quando executado no Postgres (9) e no Oracle, retorna resultados - com a ordem definida na subconsulta. No Postgres, o plano de consulta mostra que os resultados são classificados e as notas de versão do Postgres incluem o item que implica que ordens de subconsulta sejam usadas:

Evitar classificação quando a subconsulta ORDER BY corresponde à consulta superior

http://en.wikipedia.org/wiki/Order_by afirma:

Embora alguns sistemas de banco de dados permitam a especificação de uma cláusula ORDER BY em sub-seleções ou exibições de definições, a presença não tem efeito.

No entanto, a partir da minha própria verificação dos planos de consulta:

  • O SQL Server 2008 não oferece suporte a ORDER BY em uma subconsulta
  • O Postgres 9 suporta ORDER BY em uma subconsulta
  • O Oracle 10g suporta ORDER BY em uma subconsulta

Portanto, minha pergunta existe algum link que possa confirmar ou negar oficialmente que o Postgres e o Oracle não permitem a classificação em uma subconsulta?

geographika
fonte
2
Só porque você observa certos resultados não os garante. Se você deseja consistência, faça o pedido do lado de fora. Período.
Aaron Bertrand
Idealmente, é isso que será implementado. No entanto, para chegar a esse estágio envolverá alterações na lógica principal e em muitos drivers de banco de dados. Como esse problema não é relatado há muitos anos, parece que alguns dbs implementam consistentemente o ORDER BY em subconsultas. Seria bom saber quais, se possível.
geographika
2
@geographika Mesmo que alguns DBMS o façam de maneira consistente até agora, não há garantia de que eles continuarão a fazer o mesmo no futuro. Como exemplo, os aprimoramentos do MySQL no otimizador na versão 5.6 (e MariaDB 5.3) identificariam ORDER BYa subconsulta como redundante e não a classificação desnecessária.
ypercubeᵀᴹ

Respostas:

15

Você terá que fazer com que seu aplicativo não coloque ORDER BYdentro da subconsulta (talvez ele tenha uma opção para não usar uma subconsulta desnecessária em primeiro lugar). Como você já descobriu, essa sintaxe não é suportada no SQL Server sem TOP. E com TOP, a menos que você queira deixar algumas linhas de fora, o uso TOP 100 PERCENTserá ORDER BYdesativado de qualquer maneira.

E no Oracle e PostGres, apenas porque a sintaxe é suportada , não significa que seja obedecida. E apenas porque você o observa como sendo obedecido em algum cenário, não significa que continuará sendo obedecido à medida que novas versões forem lançadas ou com alterações sutis nos seus dados, estatísticas, na própria consulta ou no ambiente.

Posso garantir que, sem dúvida , se você deseja obter uma garantia sobre a ordem, precisa colocar a ORDER BYconsulta mais externa. Essa deve ser uma doutrina que você mantém próxima, independentemente da plataforma que está usando.

Você está solicitando um link que declare oficialmente que algo não é suportado. É como procurar no manual do proprietário do carro uma declaração oficial de que seu carro não pode voar.

Aaron Bertrand
fonte
Obrigado. Eu acho que o MSSQL tem a abordagem correta ao gerar um erro. O suporte e a implementação da classificação em consultas internas, quando contraria o princípio central do SQL, parece uma receita para o desastre. Não tenho certeza sobre a analogia do carro embora - você precisa adicionar procurá-lo no manual enquanto o carro está realmente voando ..
geographika
-1

Eu admito que isso é desprezível, mas se você estiver preocupado, tente retornar o número superior de linhas na subconsulta. Retornar os 100% principais não funciona, mas se você quiser passar pelo problema, pode consultar o número de linhas e passar para TOP como uma variável. Eu testei isso em um banco de dados definido para o nível de compatibilidade 80, então acho que deve funcionar com o SQL 2000.

SELECT * FROM (
        SELECT TOP (100000) ID, GEOM, Name
        FROM t
        ORDER BY Name
        ) as tbl
DBNull
fonte
Eu tentei isso originalmente e parecia classificar bem para pequenos conjuntos de dados. No entanto, quando eu estava obtendo conjuntos de registros muito grandes, a classificação se tornou aleatória novamente no SQL Server 2008R2. Talvez esteja relacionado ao tamanho da memória / página?
Geographika
Desculpe, não ajudou. Selecionar os 100% principais também fez com que a classificação fosse revertida aleatoriamente.
precisa
Isso não funcionará se a consulta for paralela, especialmente se Namenão for exclusiva. Pode não continuar funcionando em série se o otimizador escolher um índice diferente, com ordem de coluna de chave diferente.
Erik Darling