J'ai un champ varchar (100) qui contient à la fois des lettres et des chiffres. Les valeurs sont généralement sous la forme de voiture 1, voiture 10, voiture 100, voiture 20. Mais les valeurs peuvent avoir n'importe quel mot précédant le nombre. Y at-il un moyen de trier ces valeurs numériquement de sorte que la voiture 2 viendra avant la voiture 10? Merci.Comment trier une colonne VARCHAR dans un serveur SQL contenant des mots et des nombres?
Répondre
Ecrivez une fonction qui reformate les chaînes (par exemple, la voiture 10 devient la voiture 010), puis l'utilise pour transformer les données de colonne dans votre requête SQL. Vous devrez vérifier les performances de cette solution. Ou ... vous pouvez transformer les données existantes de la manière décrite ci-dessus, afin de permettre l'ordre alphabétique en SQL sans appliquer de fonctions lors de l'interrogation.
Vous aurez à comprendre le dans vos données et diviser le car 2
en un varchar car
et et int 2
.
Le modèle pourrait être aussi simple que WORD SPACE NUMBER
et vous pouvez le diviser en fonction de SPACE
en utilisant PATINDEX
ou CHARINDEX
conjointement avec SUBSTRING
.
Ensuite, vous pouvez trier par les deux colonnes.
Voici un exemple de travail
SET NOCOUNT ON
Declare @Table table
(
Id INT Identity (1, 1),
StringValue VarChar (30)
)
INSERT INTO @Table (StringValue) VALUES ('CAR 10')
INSERT INTO @Table (StringValue) VALUES ('CAR 20')
INSERT INTO @Table (StringValue) VALUES ('CAR 2')
INSERT INTO @Table (StringValue) VALUES ('CAR 3')
INSERT INTO @Table (StringValue) VALUES ('CAR 4')
INSERT INTO @Table (StringValue) VALUES ('SHIP 32')
INSERT INTO @Table (StringValue) VALUES ('SHIP 310')
INSERT INTO @Table (StringValue) VALUES ('SHIP 320')
INSERT INTO @Table (StringValue) VALUES ('SHIP 33')
INSERT INTO @Table (StringValue) VALUES ('SHIP 34')
SELECT Id,
SubString (StringValue, 1, CharIndex (' ', StringValue)) ObjectName,
CONVERT (INT, SubString (StringValue, CharIndex (' ', StringValue), LEN (StringValue))) ObjectId
FROM @Table
ORDER BY 2, 3
SELECT Id, StringValue
FROM @Table
ORDER BY
SubString (StringValue, 1, CharIndex (' ', StringValue)),
CONVERT (INT, SubString (StringValue, CharIndex (' ', StringValue), LEN (StringValue)))
WITH TABLE_NAME(NAME) AS
(
SELECT 'car 20'
UNION ALL
SELECT 'car 2'
UNION ALL
SELECT 'car 10'
)
SELECT
*
FROM TABLE_NAME
ORDER BY
SUBSTRING(NAME,1,CHARINDEX(' ',NAME,1)),CAST(SUBSTRING(NAME,CHARINDEX(' ',NAME,1)+1,100) AS INT)
SUBSTRING (NOM, 1, CHARINDEX (' ' NOM, 1)) - texte avant l'espace CAST (SUBSTRING (NOM, CHARINDEX ('' , NAME, 1) +1,100) AS INT) - texte après espace avec cast en int pour la commande correcte
La syntaxe WITH est uniquement prise en charge sur SQL Server 2005+ et l'OP n'a pas fourni la version utilisée. –
@rexem, le _WITH_ est seulement pour générer des données d'échantillon pour _ORDER BY_, il ne fait pas partie de la solution réelle ici –
Les données entrées de manière incorrecte et incohérente sont difficiles à corriger par programme. Cependant, vous devez corriger ces données, pas dans votre SELECT, donc votre ORDER BY fonctionne, mais dans les données, vous n'avez donc plus à vous en soucier.
Vous devriez envisager de créer des colonnes séparées pour les parties «mot» et «nombre» des données en question. Vous pouvez ensuite exécuter un script qui essaie de placer les données dans les colonnes appropriées, puis effectuer tout suivi manuel nécessaire. Vous aurez la possibilité de modifier la logique de l'application et éventuellement le frontal pour que les données entrant dans la base de données restent valides. Tout ce qui manque à cela se traduira par un tri inefficace des données.
Je suis avec vous, s'il y a un besoin fréquent de trier de cette façon, la seule solution raisonnable d'un perspective de performance est de stocker les données correctement. Cela peut être fait avec un déclencheur ou des champs calibrés (selon la complexité de la façon de diviser les données). – HLGEM
Que diriez-vous quelque chose comme:
SELECT
col1, col1_ltrim
, col1_sort
= CONVERT(INT
, SUBSTRING(col1_ltrim,1
, ISNULL(
NULLIF(PATINDEX('%[^0-9]%',col1_ltrim),0)-1
, LEN(col1_ltrim)
)
)
)
FROM (
SELECT col1
, col1_ltrim = STUFF(col1,1,PATINDEX('%[0-9]%',col1)-1,'')
FROM (
SELECT 'car 505' UNION ALL
SELECT 'car 95' UNION ALL
SELECT 'car 8776 blue' UNION ALL
SELECT 'car'
) a (col1)
) a
ORDER BY col1_sort
Vous pouvez envelopper dans une UDF pour la santé mentale:
CREATE FUNCTION dbo.StringToInt (@string VARCHAR(128))
RETURNS INT AS
BEGIN
SELECT @string = STUFF(@string,1,PATINDEX('%[0-9]%',@string)-1,'')
RETURN CONVERT(INT
, SUBSTRING(@string,1
, ISNULL(
NULLIF(PATINDEX('%[^0-9]%',@string),0)-1
, LEN(@string)
)
)
)
END
GO
SELECT col1, col1_sort = dbo.StringToInt(col1)
FROM (
SELECT 'car 505' UNION ALL
SELECT 'car 95' UNION ALL
SELECT 'car 8776 blue' UNION ALL
SELECT 'car'
) a (col1)
ORDER BY col1_sort
Vous pouvez profiter du fait que
patindex('%...', _col_)
correspond à la le dernier caractère et
patindex('%...%', _col_)
correspond à n'importe quel nombre de caractères.Aussi longtemps que les chiffres sont à la fin de la valeur de la colonne, vous pouvez facilement extraire la valeur numérique de la colonne (StackOverflow ne me laisse pas mettre le mot UNION dans un UUU post-remplacement avec UNION):
select Rec,
case
when patindex('%[0-9]', Rec) > 0
then left(Rec, patindex('%[0-9]%', Rec)-1)
else Rec
end,
case
when patindex('%[0-9]', Rec) > 0
then cast(right(Rec, len(Rec)-patindex('%[0-9]%', Rec)+1) as int)
end
from (select 'SHIP34' Rec UUU select 'SHIP 33' UUU select 'SHIP 320' UUU select 'SHIP310' UUU select 'SHIP32' UUU select 'CAR 4X' UUU select 'CAR 4' UUU select 'CAR3' UUU select 'CAR 2' UUU select 'CAR20' UUU select 'CAR 10') TestData
order by
case
when patindex('%[0-9]', Rec) > 0
then left(Rec, patindex('%[0-9]%', Rec)-1)
else Rec
end,
case
when patindex('%[0-9]', Rec) > 0
then cast(right(Rec, len(Rec)-patindex('%[0-9]%', Rec)+1) as int)
end
- 1. Comment concaténer des nombres et des chaînes pour formater des nombres dans T-SQL?
- 2. Comment inverser les mots dans une colonne
- 3. Meilleure façon de rechercher dans une colonne varchar dans le serveur SQL
- 4. Comment trier gridview par colonne contenant un nombre entier nul?
- 5. fonction serveur Sql pour afficher la fréquence des mots dans une colonne
- 6. Tri des chaînes contenant des nombres d'une manière conviviale
- 7. Modifier le type d'une colonne avec des nombres de varchar à int
- 8. Comment puis-je transformer une table avec 1 ligne avec des colonnes varchar dans une colonne?
- 9. Comment écrire dans une colonne varchar (max) en utilisant ODBC
- 10. Comment afficher les enregistrements contenant des informations spécifiques dans SQl
- 11. Faire correspondre des lignes contenant un mot avec des permutations
- 12. Modification d'un enregistrement dans une table (serveur SQL) contenant des clés étrangères?
- 13. Comment faire une colonne de mémo sur une grille DX afficher des mots partiels?
- 14. Supprimer des données invalides de la colonne VarChar
- 15. Mise en forme des données varchar dans un certain format
- 16. SQL Server: trier une colonne numériquement si possible, sinon alpha
- 17. Comment trier par nom de colonne réservé dans ce contexte?
- 18. Méthode efficace pour interroger un champ Varchar délimité dans SQL
- 19. Serveur SQL: convertir des lignes en colonnes
- 20. comment rechercher des mots entiers efficacement dans un sqlite db
- 21. Opérateurs arithmétiques contre les données varchar dans le serveur SQL
- 22. Se débarrasser des nombres "Magic" dans SQL Server
- 23. Sites Web contenant des scripts utiles et fiables pour le serveur SQL?
- 24. Regexp pour faire correspondre des nombres et des unités dans un fragment HTML?
- 25. Trier une liste de nombres saisis par l'utilisateur dans MIPS
- 26. SQL Server VARCHAR (10)
- 27. Comment modifier une colonne et une colonne calculée
- 28. Comment utiliser un index basé sur une fonction sur une colonne contenant des valeurs NULL dans Oracle 10+?
- 29. MS SQL FTI - la recherche sur "n *" renvoie des nombres
- 30. Comment trier un NSMutableArray de NSMutableArrays contenant NSStrings?
Il ya des questions similaires à ce sujet - recherche de "natural number sorting sql" - vous obtiendrez des entrées comme celle-ci: http://stackoverflow.com/questions/153633/natural-sort-in-mysql – schnaader
Plate-forme sql utilisez-vous? – avguchenko