J'ai trouvé une question répondue avec la Row_Number()
fonction dans la clause where. Lorsque j'ai essayé une requête, j'obtenais l'erreur suivante:
"Msg 4108, Niveau 15, État 1, Ligne 1 Les fonctions fenêtrées ne peuvent apparaître que dans les clauses SELECT ou ORDER BY."
Voici la requête que j'ai essayée. Si quelqu'un sait comment résoudre ce problème, faites-le moi savoir.
SELECT employee_id
FROM V_EMPLOYEE
WHERE row_number() OVER ( ORDER BY employee_id ) > 0
ORDER BY Employee_ID
sql
sql-server
tsql
analytic-functions
johnnyRose
la source
la source
ROW_NUMBER() OVER (ORDER BY employee_id) > 0
évaluera toujours àTRUE
Réponses:
Pour contourner ce problème, enveloppez votre instruction select dans un CTE, puis vous pouvez interroger le CTE et utiliser les résultats de la fonction fenêtrée dans la clause where.
la source
ROW_NUMBER()
inWHERE
sans CTE :(Notez que ce filtre est redondant:
ROW_NUMBER()
commence à partir de1
et est toujours supérieur à0
.la source
AS q
place, mais cela fonctionnerait non plus).rn
est un acronyme universellement accepté pour le numéro de ligne de nos jours. Essayez de taper "row_number over as ..." dans la chaîne de recherche Google et voyez ce qu'il vous suggère.la source
Je pense que vous voulez quelque chose comme ça:
la source
From V_EMPLOYEE) A
ajouter A comme alias.En réponse aux commentaires sur la réponse de rexem, pour savoir si une vue en ligne ou un CTE serait plus rapide, j'ai refondu les requêtes pour utiliser une table que je, et tout le monde, avait disponible: sys.objects.
Les plans de requête produits étaient exactement les mêmes. Je m'attendrais à ce que dans tous les cas, l'optimiseur de requêtes propose le même plan, au moins en simple remplacement de CTE par une vue en ligne ou vice versa.
Bien sûr, essayez vos propres requêtes sur votre propre système pour voir s'il y a une différence.
De plus,
row_number()
dans la clause where, il y a une erreur courante dans les réponses données sur Stack Overflow. La logiquerow_number()
n'est pas disponible tant que la clause select n'est pas traitée. Les gens oublient cela et quand ils répondent sans tester la réponse, la réponse est parfois fausse. (Une accusation dont j'ai moi-même été coupable.)la source
J'ai l'impression que toutes les réponses montrant l'utilisation d'un CTE ou d'une sous-requête sont des correctifs suffisants pour cela, mais je ne vois personne entrer au cœur des raisons pour lesquelles OP a un problème. La raison pour laquelle ce que l'OP suggéré ne fonctionne pas est due à l'ordre logique de traitement des requêtes ici:
Je pense que cela contribue grandement à la réponse, car cela explique pourquoi des problèmes comme celui-ci se produisent.
WHERE
est toujours traité avant d'SELECT
effectuer une CTE ou une sous-requête nécessaire pour de nombreuses fonctions. Vous verrez cela souvent dans SQL Server.la source
Utilisation de CTE (SQL Server 2005+):
Utilisation de la vue en ligne / alternative équivalente non CTE:
la source
SQL Server
,CTE
l » et des vues en ligne sont la même chose et ont les mêmes performances. Lorsque des fonctions non déterministes sont utilisées dans aCTE
, elles sont réévaluées à chaque appel. Il faut utiliser de sales trucs pour forcer la matérialisation d'unCTE
. Voir ces articles dans mon blog: explainextended.com/2009/07/28/... explainextended.com/2009/05/28/generating-xml-in-subqueriesbasé sur la réponse d'OP à la question:
"méthode 1" est comme la requête du PO à partir de la question liée, et "méthode 2" est comme la requête de la réponse sélectionnée. Vous deviez regarder le code lié dans cette réponse pour voir ce qui se passait réellement, car le code de la réponse sélectionnée avait été modifié pour que cela fonctionne. Essaye ça:
PRODUCTION:
la source
la source
la source