web-dev-qa-db-fra.com

Fonction SQL Row_Number () dans une clause Where sans ORDER BY?

J'ai trouvé un tas de questions sur ce sujet avec des solutions de Nice mais aucune d'entre elles ne traite réellement de ce qu'il faut faire si les données ne doivent pas être classées d'une manière spécifique. Par exemple, la requête suivante:

WITH MyCte AS 
(
    select   employee_id,
             RowNum = row_number() OVER ( order by employee_id )
    from     V_EMPLOYEE 
    ORDER BY Employee_ID
)
SELECT  employee_id
FROM    MyCte
WHERE   RowNum > 0

fonctionne bien si les données doivent être ordonnées par employee_id. Mais que se passe-t-il si mes données ne comportent pas d’ordre spécifique mais que les numéros de rangée jouent eux-mêmes le rôle d’ID? Mon but est d'écrire une requête comme celle-ci (avec la fonction Row_Number() n'ayant pas de clause ORDER BY):

WITH MyCte AS 
(
    select   employee_id,
             RowNum = row_number() OVER ( <PRESERVE ORIGINAL ORDER FROM DB> )
    from     V_EMPLOYEE 
    ORDER BY Employee_ID
)
SELECT  employee_id
FROM    MyCte
WHERE   RowNum > 0

EDIT: Lors de la recherche sur Google, j'ai compris que ce n'est pas vraiment possible. Certains peuvent-ils suggérer une solution de contournement pour cela?

41
Legend

Juste au cas où cela serait utile à quelqu'un d'autre. Je viens de le comprendre de ailleurs :

WITH MyCte AS 
(
    select   employee_id,
             RowNum = row_number() OVER (ORDER BY (SELECT 0))
    from     V_EMPLOYEE 
    ORDER BY Employee_ID
)
SELECT  employee_id
FROM    MyCte
WHERE   RowNum > 0
92
Legend

J'utilise ceci pour supprimer le genre:

ORDER BY @@rowcount

@@ rowcount est constant dans la requête. Exemple:

select N = row_number() over (order by @@rowcount) from sys.columns

L'utilisation de (sélectionnez 0) dans ORDER BY semble être beaucoup plus lente.

21
kaborka

Le vrai problème avec l’approche que vous proposez est que l’ordre dans la base de données n’est pas garanti. Il se peut que, par coïncidence, il retourne à votre application dans le même ordre tout le temps, mais SQL Standard ne garantit pas cet ordre et peut changer en fonction des modifications de version ou d’édition. L'ordre des données d'un serveur SQL n'est pas garanti sans une clause order by. Cette conception serait simplement fondée sur la «chance». Si cette variation possible de l’ordre a un impact sur votre implémentation, vous pouvez la modifier maintenant avant d’aller trop loin dans la mise en œuvre.

Bon article sur ce sujet

6
doug_w

Il n'y a pas une telle chose comme ORIGINAL ORDER. Le serveur SQL ne peut pas garantir l'ordre des lignes si vous ne spécifiez pas ORDER BY. Vous pouvez avoir de la chance et obtenir des résultats dans un ordre particulier, mais cela peut changer à tout moment.

4
Tomas Kirda

Il existe une solution plus simple que la précédente. Vous pouvez toujours utiliser ROW_NUMBER mais fournir une valeur arbitraire dans la clause Order by: 

Select firstName, lastName, ROW_NUMBER() OVER (ORDER BY (SELECT 1)) from tblPerson
1
Zphunk