web-dev-qa-db-fra.com

ROW_NUMBER Sans ORDER BY

Je dois ajouter un numéro de ligne dans ma requête existante afin de pouvoir suivre le nombre de données ajoutées dans Redis. Si ma requête a échoué, je peux donc partir de cette ligne no qui est mis à jour dans une autre table.

Requête pour démarrer les données après 1000 lignes de la table

SELECT * FROM (SELECT *, ROW_NUMBER() OVER (Order by (select 1)) as rn ) as X where rn > 1000

La requête fonctionne bien. Si d’une manière que je puisse obtenir la ligne non sans utiliser order by.

Quel est select 1 ici?

La requête est optimisée ou je peux le faire par d'autres moyens. S'il vous plaît fournir la meilleure solution.

20
lucy

Il n'y a pas besoin de s'inquiéter de la spécification de constante dans le ORDER BY expression. Ce qui suit est tiré de T-SQL hautes performances Microsoft SQL Server 2012 utilisant des fonctions de fenêtre écrit par Itzik Ben-Gan _ (il était disponible en téléchargement gratuit sur le site de livres électroniques gratuits de Microsoft):

Comme mentionné précédemment, une clause de commande de fenêtre est obligatoire et SQL Server n'autorise pas le classement sur une constante, par exemple ORDER BY NULL. Mais, de manière surprenante, lors du passage d’une expression basée sur une sous-requête renvoyant une constante, par exemple ORDER BY (SELECT NULL), SQL Server l’acceptera. En même temps, l'optimiseur dés-imbrique ou développe l'expression et réalise que l'ordre est le même pour toutes les lignes. Par conséquent, il supprime la nécessité de commander des données d'entrée. Voici une requête complète démontrant cette technique:

SELECT actid, tranid, val,
 ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS rownum
FROM dbo.Transactions;

enter image description here

Observez dans les propriétés de l'itérateur d'analyse d'index que la propriété Ordered a la valeur False, ce qui signifie que l'itérateur n'est pas obligé de renvoyer les données dans l'ordre des clés d'index.


Ce qui précède signifie que lorsque vous utilisez un ordre constant, il n’est pas effectué. Je recommanderai fortement de lire le livre comme Itzik Ben-Gan décrit en détail le fonctionnement des fonctions de la fenêtre et l’optimisation de divers cas lorsqu’elles sont utilisées.

45
gotqn

Essayez juste order by 1. Lisez le message d'erreur. Puis rétablissez la order by (select 1). Sachez que celui qui a écrit cela a, à un moment donné, lu le message d'erreur et a ensuite décidé que la bonne chose à faire était de tromper le système pour qu'il ne génère pas d'erreur plutôt que de réaliser la vérité fondamentale à laquelle l'erreur tentait de les alerter.

Les tables n'ont pas d'ordre inhérent. Si vous voulez une forme de commande sur laquelle vous pouvez compter, c'est à vous de fournir suffisamment d'expression (s) déterministe (s) pour chaque clause ORDER BY De telle sorte que chaque ligne soit identifiée et ordonnée de manière unique.

Tout ce qui reste à faire, y compris inciter le système à ne pas émettre d’erreur, est espère que le système fera quelque chose de raisonnable sans utiliser les outils qui vous ont été fournis pour s’assurer qu’il fait quelque chose de raisonnable - une clause bien spécifiée ORDER BY.

6

Vous pouvez utiliser n'importe quelle valeur littérale

ex

order by (select 0)

order by (select null)

order by (select 'test')

etc

Reportez-vous à cela pour plus d'informations https://exploresql.com/2017/03/31/row_number-function-with-no-specific-order/

4
Madhivanan