Question

J'ai des données mixtes dans la colonne nvarchar (mots et chiffres). Quel est le moyen le plus rapide de trier les données de cette colonne en ordre numérique

Exemple de résultat:

  • 1
  • 2
  • 3
  • ...
  • 10
  • 11
  • ...
  • aaaa
  • aaab
  • b
  • ba
  • ba
  • ...
Était-ce utile?

La solution

Utilisez ceci:

ORDER BY
    CASE WHEN ISNUMERIC(column) = 1 THEN 0 ELSE 1 END,
    CASE WHEN ISNUMERIC(column) = 1 THEN CAST(column AS INT) ELSE 0 END,
    column

Cela fonctionne comme prévu.

Remarque : vous dites le moyen le plus rapide . Ce sql a été rapide pour moi à produire, mais le plan d'exécution montre un scan de table, suivi d'un calcul scalaire. Cela pourrait éventuellement produire un résultat temporaire contenant toutes les valeurs de cette colonne avec des colonnes temporaires supplémentaires pour les résultats ISNUMERIC. L’exécution n’est peut-être pas rapide.

Autres conseils

Si vous laissez vos chiffres avec des 0 et que vous triez dessus, vous obtiendrez les résultats souhaités. Vous devez vous assurer que le nombre de 0 avec lesquels vous remplissez correspond à la taille de la colonne varchar.

Regardez cet exemple ...

Declare @Temp Table(Data VarChar(20))

Insert Into @Temp Values('1')
Insert Into @Temp Values('2')
Insert Into @Temp Values('3')
Insert Into @Temp Values('10')
Insert Into @Temp Values('11')
Insert Into @Temp Values('aaaa')
Insert Into @Temp Values('aaab')
Insert Into @Temp Values('b')
Insert Into @Temp Values('ba')
Insert Into @Temp Values('ba')

Select * From @Temp
Order By Case When IsNumeric(Data) = 1 
              Then Right('0000000000000000000' + Data, 20) 
              Else Data End

Notez également qu'il est important, lors de l'utilisation d'une instruction case, que chaque branche de cette instruction renvoie le même type de données, sinon vous obtiendrez des résultats incorrects ou une erreur.

- vérifier l'existence de l'événement
si existe (sélectionnez * à partir de dbo.sysobjects où [id] = id_objet (N'dbo.t ') AND propriété (id, N'IsUserTable') = 1)
    déposer la table dbo.t
aller

- crée un exemple de table
create table dbo.t (c varchar (10) non null)

mettre nocount sur

- peupler l'exemple de table
insérer dans dbo.t (c) les valeurs ('1')
insérer dans dbo.t (c) les valeurs ('2')
insérer dans les valeurs dbo.t (c) ('3')
insérer dans les valeurs dbo.t (c) ('10 ')
insérer dans dbo.t (c) les valeurs ('11')
insérer dans dbo.t (c) les valeurs ('aaaa')
insérer dans dbo.t (c) les valeurs ('aaab')
insérer dans dbo.t (c) des valeurs ('b')
insérer dans dbo.t (c) les valeurs ('ba')
insérer dans dbo.t (c) des valeurs ('ba')

- renvoyer les données
sélectionnez c dans dbo.t
classer par cas quand isnumeric (c) = 1 alors 0 sinon 1 fin,
cas où isnumeric (c) = 1 alors jeté (c as int) sinon 0 end,
c

Vous pouvez traiter les données comme alphanumériques ou numériques, mais pas les deux à la fois. Je ne pense pas que ce que vous essayez de faire soit possible, le modèle de données n’est pas configuré de manière appropriée.

  

Je ne pense pas ce que vous essayez de faire   est possible

Cet exemple fonctionne bien

SELECT * FROM TableName
ORDER BY CASE WHEN 1 = IsNumeric(ColumnName) THEN Cast(ColumnName AS INT) END

Le résultat est:

  • a
  • b
  • c
  • ...
  • 1
  • 2
  • 3

Mais il me faut d’abord des chiffres.

Cela devrait fonctionner:

select * from Table order by ascii(Column)

Jetez-le.

SELECT * FROM foo ORDER BY CAST(somecolumn AS int);

Cela fait longtemps que je n’ai pas touché SQL Server, ma syntaxe est peut-être tout à fait incorrecte:)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top