-1
votes

SQL Server - Utilisation de la fonction de partition Row_Number () sur la fonction pour définir une valeur

Bonjour tout le monde Merci d'avoir pris du temps à regarder ma question,

fond strong> p>

J'utilise la fonction Row_Numer () avec une partition par .. Commande par déclaration pour définir une valeur Varcharne avec une valeur INT incrémentée à la fin de celle-ci pour chacune d'une valeur dans l'une de mes tables. P> xxx pré>

ici la valeur "cf ' passe de cf1-cfx pour chaque composant_module_id p>

 Sortie d'échantillon de requête P>

Ma question forte> p>

Chaque fois que J'essaie d'utiliser ces valeurs CF ailleurs, comme enregistrées dans une table Temp, d'autres instructions de commande et de regroupement modifient ces valeurs. C'est comme si les déclarations de générer les valeurs des «CF» sont enregistrées et non les valeurs «CF» elles-mêmes. P>

Après avoir inséré la requête ci-dessus dans une table Temp #T - P>

SELECT * FROM #t ORDER BY cf


4 commentaires

C'est normal que si vous commandez par un champ Varchark 10 vient avant 2 et 100 viennent avant 2


Vous construisez explicitement les valeurs de Varchark, lorsque vous comparez des caractères, 1 <10 <2, mais 01 <02 <10


On dirait que tu ferais mieux de stocker la valeur int et à l'aide d'une colonne calculée ( persisté ) pour concaténer votre préfixe et Row_Number valeur .


Je ne suis pas confondu à propos de CF1 trié avant CF10 et CF100. Les valeurs réelles doivent être CF1-CF29. Je ne devrais pas obtenir de valeurs supérieures à cf29. Ma question est, comment puis-je trier les valeurs correctes (CF1-CF29) sans générer ces valeurs incorrectes (CF100, CF200, etc.).


4 Réponses :


0
votes

Essayez ceci xxx

Le comportement que vous rencontrez est parce que varchar commandes en effectuant un tri alphabétique

Vous devez faire le Commander à l'aide d'un INT , puis faites votre concaténation à la fin (en enveloppant la requête d'origine dans une sous-requête

Cependant, une meilleure solution a été suggérée dans les commentaires qui doivent Seulement des numéros de magasin comme int et ajoutez le préfixe à l'aide d'une colonne calculée (ou au niveau de la requête)


2 commentaires

Je ne suis pas confondu à propos de CF1 trié avant CF10 et CF100. Les valeurs réelles doivent être CF1-CF29. Je ne devrais pas obtenir de valeurs supérieures à cf29. Ma question est, comment puis-je trier les valeurs correctes (CF1-CF29) sans générer ces valeurs incorrectes (CF100, CF200, etc.).


Vous devez modifier votre question afin que nous puissions voir la sortie pour les "mauvais" résultats



0
votes

Si vous le faites de cette façon, cela fonctionnera

SELECT * FROM #t ORDER BY component_module_id, cast(replace(cf, 'cf', '') as int)


0 commentaires

0
votes

Le problème est que vous partitionnez tous les deux par et commande par composant_module_id . Dans chaque partition, les clés de commande ont la même valeur.

Pourquoi cela compte-t-il? Le tri en SQL n'est pas stable. Cela signifie que les liens peuvent être résolus de toute façon. Exécutez la requête une seconde fois et vous pourriez avoir une commande différente (parmi les liens).

La solution simple consiste à modifier la commande pour être stable et que vous avez juste la colonne de faire ce composant_property_id . Je recommanderais également d'utiliser concat () de sorte que vous n'avez pas besoin de conversions de type: xxx

Je dois également noter que votre code utilise Varchar sans longueur. C'est une très mauvaise idée dans SQL Server. La longueur par défaut varie selon le contexte et peut ne pas être suffisamment grande pour certaines valeurs (bien que vous n'ayez pas ce problème dans ce cas).


0 commentaires

0
votes

mise à jour

J'ai pris la suggestion de Larnu,

"On dirait que tu ferais mieux de stocker la valeur int, et utilise une colonne calculée (persistée) pour concaténer votre préfixe et Row_Number la valeur. "

et mes valeurs «CF» apparaissent maintenant correctement après avoir été triée. Merci tout le monde marquage comme résolu.


0 commentaires