Aimez-vous analyser les chaînes ? Si tel est le cas, l'une des fonctions de chaîne indispensables à utiliser est SQL SUBSTRING. C'est l'une de ces compétences qu'un développeur devrait avoir pour n'importe quel langage.
Alors, comment faites-vous ?
Points importants dans l'analyse de chaînes
Supposons que vous êtes nouveau dans l'analyse. Quels points importants devez-vous retenir ?
- Savoir quelles informations sont intégrées dans la chaîne.
- Obtenez les positions exactes de chaque élément d'information dans une chaîne. Vous devrez peut-être compter tous les caractères de la chaîne.
- Connaître la taille ou la longueur de chaque élément d'information dans une chaîne.
- Utilisez la bonne fonction de chaîne qui peut facilement extraire chaque élément d'information de la chaîne.
Connaître tous ces facteurs vous préparera à utiliser SQL SUBSTRING() et à lui transmettre des arguments.
Syntaxe SQL SUBSTRING
La syntaxe de SQL SUBSTRING est la suivante :
SUBSTRING(expression chaîne, début, longueur)
- expression de chaîne – un chaîne littérale ou une expression SQL qui renvoie une chaîne.
- commencer – un numéro où l'extraction commencera. Il est également basé sur 1 - le premier caractère de l'argument de l'expression de chaîne doit commencer par 1 et non par 0. Dans SQL Server, il s'agit toujours d'un nombre positif. Dans MySQL ou Oracle, cependant, il peut être positif ou négatif. Si négatif, l'analyse commence à partir de la fin de la chaîne.
- longueur – la longueur des caractères à extraire. SQL Server l'exige. Dans MySQL ou Oracle, c'est facultatif.
4 exemples de SOUS-CHAÎNE SQL
1. Utilisation de SQL SUBSTRING pour extraire d'une chaîne littérale
Commençons par un exemple simple utilisant une chaîne littérale. Nous utilisons le nom d'un célèbre groupe féminin coréen, BlackPink, et la figure 1 illustre le fonctionnement de SUBSTRING :
Le code ci-dessous montre comment nous allons l'extraire :
-- extract 'black' from BlackPink (English)
SELECT SUBSTRING('BlackPink',1,5) AS result
Maintenant, examinons également le jeu de résultats de la figure 2 :
N'est-ce pas facile ?
Pour extraire le noir de BlackPink , vous partez de la position 1 et finissez en position 5. Depuis BlackPink est coréen, découvrons si SUBSTRING fonctionne sur les caractères coréens Unicode.
(AVIS DE NON-RESPONSABILITÉ :Je ne peux pas parler, lire ou écrire le coréen, j'ai donc obtenu la traduction coréenne de Wikipedia. J'ai également utilisé Google Traduction pour voir quels caractères correspondent au noir et Rose . Veuillez m'excuser si c'est faux. Pourtant, j'espère que le point que j'essaie de clarifier viendra à travers)
Prenons la chaîne en coréen (voir Figure 3). Les caractères coréens utilisés se traduisent par BlackPink :
Maintenant, voyez le code ci-dessous. Nous allons extraire deux caractères correspondant à Noir .
-- extract 'black' from BlackPink (Korean)
SELECT SUBSTRING(N'블랙핑크',1,2) AS result
Avez-vous remarqué la chaîne coréenne précédée de N ? Il utilise des caractères Unicode, et le serveur SQL suppose NVARCHAR et doit être précédé de N . C'est la seule différence dans la version anglaise. Mais tournera-t-il bien ? Voir Figure 4 :
Il a fonctionné sans erreur.
2. Utilisation de SQL SUBSTRING dans MySQL avec un argument de début négatif
Avoir un argument de départ négatif ne fonctionnera pas dans SQL Server. Mais nous pouvons en avoir un exemple en utilisant MySQL. Cette fois, extrayons Rose de BlackPink . Voici le code :
-- Extract 'Pink' from BlackPink using MySQL Substring (English)
select substring('BlackPink',-4,4) as result;
Maintenant, obtenons le résultat dans la figure 5 :
Comme nous avons passé -4 au paramètre start, l'extraction a commencé à partir de la fin de la chaîne, en reculant de 4 caractères. Pour obtenir le même résultat dans SQL Server, utilisez la fonction RIGHT().
Les caractères Unicode fonctionnent également avec MySQL SUBSTRING, comme vous pouvez le voir sur la figure 6 :
Cela a très bien fonctionné. Mais avez-vous remarqué que nous n'avions pas besoin de faire précéder la chaîne par N ? Notez également qu'il existe plusieurs façons d'obtenir une sous-chaîne dans MySQL. Vous avez déjà vu SUBSTRING. Les fonctions équivalentes dans MySQL sont SUBSTR() et MID().
3. Analyser des sous-chaînes avec des arguments de début et de longueur variables
Malheureusement, toutes les extractions de chaînes n'utilisent pas des arguments de début et de longueur fixes. Dans un tel cas, vous avez besoin de CHARINDEX pour obtenir la position d'une chaîne que vous ciblez. Prenons un exemple :
DECLARE @lineString NVARCHAR(30) = N'김제니 01/16/[email protected]'
DECLARE @name NVARCHAR(5)
DECLARE @bday DATE
DECLARE @instagram VARCHAR(20)
SET @name = SUBSTRING(@lineString,1,CHARINDEX('@',@lineString)-11)
SET @bday = SUBSTRING(@lineString,CHARINDEX('@',@lineString)-10,10)
SET @instagram = SUBSTRING(@lineString,CHARINDEX('@',@lineString),30)
SELECT @name AS [Name], @bday AS [BirthDate], @instagram AS [InstagramAccount]
Dans le code ci-dessus, vous devez extraire un nom en coréen, la date de naissance et le compte Instagram.
Nous commençons par définir trois variables pour contenir ces informations. Après cela, nous pouvons analyser la chaîne et attribuer les résultats à chaque variable.
Vous pensez peut-être qu'il est plus simple d'avoir des débuts et des longueurs fixes. De plus, nous pouvons l'identifier en comptant les caractères manuellement. Mais que se passe-t-il si vous en avez beaucoup sur une table ?
Voici notre analyse :
- Le seul élément fixe dans la chaîne est le @ personnage dans le compte Instagram. Nous pouvons obtenir sa position dans la chaîne en utilisant CHARINDEX. Ensuite, nous utilisons cette position pour obtenir le début et les longueurs du reste.
- La date de naissance est dans un format fixe utilisant MM/dd/yyyy avec 10 caractères.
- Pour extraire le nom, nous commençons à 1. Puisque la date de naissance comporte 10 caractères plus le @ caractère, vous pouvez accéder au caractère de fin du nom dans la chaîne. De la position du @ caractère, nous reculons de 11 caractères. La SOUS-CHAINE(@lineString,1,CHARINDEX(‘@’,@lineString)-11) est la voie à suivre.
- Pour obtenir la date de naissance, nous appliquons la même logique. Obtenir la position du @ caractère et reculez de 10 caractères pour obtenir la valeur de début de la date de naissance. 10 est une longueur fixe. SOUS-CHAINE(@lineString,CHARINDEX(‘@’,@lineString)-10,10) est de savoir comment obtenir la date de naissance.
- Enfin, obtenir un compte Instagram est simple. Commencez à partir de la position du @ caractère à l'aide de CHARINDEX. Remarque :30 est la limite de nom d'utilisateur Instagram.
Consultez les résultats dans la figure 7 :
4. Utilisation de SQL SUBSTRING dans une instruction SELECT
Vous pouvez également utiliser SUBSTRING dans l'instruction SELECT, mais nous devons d'abord disposer de données de travail. Voici le code :
SELECT
CAST(P.LastName AS CHAR(50))
+ CAST(P.FirstName AS CHAR(50))
+ CAST(ISNULL(P.MiddleName,'') AS CHAR(50))
+ CAST(ea.EmailAddress AS CHAR(50))
+ CAST(a.City AS CHAR(30))
+ CAST(a.PostalCode AS CHAR(15)) AS line
INTO PersonContacts
FROM Person.Person p
INNER JOIN Person.EmailAddress ea
ON P.BusinessEntityID = ea.BusinessEntityID
INNER JOIN Person.BusinessEntityAddress bea
ON P.BusinessEntityID = bea.BusinessEntityID
INNER JOIN Person.Address a
ON bea.AddressID = a.AddressID
Le code ci-dessus forme une longue chaîne contenant le nom, l'adresse e-mail, la ville et le code postal. Nous voulons également le stocker dans les PersonContacts tableau.
Maintenant, obtenons le code pour désosser en utilisant SUBSTRING :
SELECT
TRIM(SUBSTRING(line,1,50)) AS [LastName]
,TRIM(SUBSTRING(line,51,50)) AS [FirstName]
,TRIM(SUBSTRING(line,101,50)) AS [MiddleName]
,TRIM(SUBSTRING(line,151,50)) AS [EmailAddress]
,TRIM(SUBSTRING(line,201,30)) AS [City]
,TRIM(SUBSTRING(line,231,15)) AS [PostalCode]
FROM PersonContacts pc
ORDER BY LastName, FirstName
Puisque nous avons utilisé des colonnes de taille fixe, il n'est pas nécessaire d'utiliser CHARINDEX.
Utiliser SQL SUBSTRING dans une clause WHERE – Un piège de performance ?
C'est vrai. Personne ne peut vous empêcher d'utiliser SUBSTRING dans une clause WHERE. C'est une syntaxe valide. Mais que se passe-t-il si cela cause des problèmes de performances ?
C'est pourquoi nous le prouvons avec un exemple, puis discutons de la façon de résoudre ce problème. Mais d'abord, préparons nos données :
USE AdventureWorks
GO
SELECT * INTO SalesOrders FROM Sales.SalesOrderHeader soh
Je ne peux pas gâcher le SalesOrderHeader table, donc je l'ai vidé sur une autre table. Ensuite, j'ai créé le SalesOrderID dans les nouveaux SalesOrders table une clé primaire.
Maintenant, nous sommes prêts pour la requête. J'utilise dbForge Studio pour SQL Server avec le mode de profilage des requêtes activé pour analyser les requêtes.
SELECT
so.SalesOrderID
,so.OrderDate
,so.CustomerID
,so.AccountNumber
FROM SalesOrders so
WHERE SUBSTRING(so.AccountNumber,4,4) = '4030'
Comme vous le voyez, la requête ci-dessus fonctionne correctement. Maintenant, regardez le diagramme de plan de profil de requête dans la figure 8 :
Le diagramme de plan semble simple, mais examinons les propriétés du nœud Clustered Index Scan. En particulier, nous avons besoin des informations d'exécution :
L'illustration 9 montre 785 * pages de 8 Ko lues par le moteur de base de données. Notez également que le nombre réel de lignes lues est de 31 411. C'est le nombre total de lignes dans la table. Cependant, la requête n'a renvoyé que 27 605 lignes réelles.
La table entière a été lue en utilisant l'index clusterisé comme référence.
Pourquoi ?
Le fait est que le serveur SQL doit savoir si 4030 est une sous-chaîne d'un numéro de compte. Il doit lire et évaluer chaque enregistrement. Ignorez les lignes qui ne sont pas égales et renvoyez les lignes dont nous avons besoin. Il fait le travail mais pas assez vite.
Que pouvons-nous faire pour l'accélérer ?
Évitez les SUBSTRING dans la clause WHERE et obtenez le même résultat plus rapidement
Ce que nous voulons maintenant, c'est obtenir le même résultat sans utiliser SUBSTRING dans la clause WHERE. Suivez les étapes ci-dessous :
- Modifier le tableau en ajoutant une colonne calculée avec une SUBSTRING(AccountNumber, 4,4) formule. Appelons-le AccountCategory à défaut d'un meilleur terme.
- Créer un index non clusterisé pour la nouvelle AccountCategory colonne. Inclure la date de commande , numéro de compte , et ID client colonnes.
C'est tout.
Nous modifions la clause WHERE de la requête pour adapter la nouvelle AccountCategory colonne :
SET STATISTICS IO ON
SELECT
so.SalesOrderID
,so.OrderDate
,so.CustomerID
,so.AccountNumber
FROM SalesOrders so
WHERE so.AccountCategory = '4030'
SET STATISTICS IO OFF
Il n'y a pas de SUBSTRING dans la clause WHERE. Maintenant, vérifions le diagramme de plan :
Index Scan a été remplacé par Index Seek. Notez également que SQL Server a utilisé le nouvel index sur la colonne calculée. Y a-t-il également des changements dans les lectures logiques et les lignes réelles lues ? Voir Figure 11 :
Passer de 785 à 222 lectures logiques est une grande amélioration, plus de trois fois moins que les lectures logiques d'origine. Il a également réduit la lecture des lignes réelles aux seules lignes dont nous avons besoin.
Ainsi, l'utilisation de SUBSTRING dans la clause WHERE n'est pas bonne pour les performances, et cela vaut pour toute autre fonction à valeur scalaire utilisée dans la clause WHERE.
Conclusion
- Les développeurs ne peuvent pas éviter d'analyser les chaînes. D'une manière ou d'une autre, un besoin s'en fera sentir.
- Lors de l'analyse de chaînes, il est essentiel de connaître les informations contenues dans la chaîne, les positions de chaque élément d'information et leurs tailles ou longueurs.
- L'une des fonctions d'analyse est SQL SUBSTRING. Il n'a besoin que de la chaîne à analyser, de la position pour démarrer l'extraction et de la longueur de la chaîne à extraire.
- SUBSTRING peut avoir des comportements différents entre les versions SQL telles que SQL Server, MySQL et Oracle.
- Vous pouvez utiliser SUBSTRING avec des chaînes littérales et des chaînes dans des colonnes de table.
- Nous avons également utilisé SUBSTRING avec des caractères Unicode.
- L'utilisation de SUBSTRING ou de toute fonction à valeur scalaire dans la clause WHERE peut réduire les performances des requêtes. Corrigez cela avec une colonne calculée indexée.
Si vous trouvez cet article utile, partagez-le sur vos plateformes de réseaux sociaux préférées ou partagez votre commentaire ci-dessous ?