-1
votes

SQL diviser le prénom avec un soulignement

J'essaie de scinder le prénom du deuxième prénom ou de la première initiale quand il y a un soulignement dans le nom. J'ai pu diviser le prénom du deuxième prénom quand il y a un espace, mais que vous avez des problèmes avec le soulignement.

Je voudrais tout maintenir ensemble dans la déclaration de cas si possible. P>

    SELECT 
[first name]
,  SUBSTRING([first name], 1,
                  CASE WHEN SUBSTRING(REVERSE([first name]), 2, 1) = ' '
                       THEN CHARINDEX(' ', [first name]) - 1
                       ELSE LEN([first name])
                  END) AS FirstName ,
        CASE WHEN SUBSTRING(REVERSE([first name]), 2, 1) = ' '
             THEN SUBSTRING([first name], LEN([first name]), 1)
             ELSE NULL
        END AS MiddleName
,   [Last Name]

FROM nametable


5 commentaires

Pourquoi ne remplacez-vous pas le soulignement avec un espace?


Non, je veux retirer le soulignement et séparer le deuxième prénom ou l'initiale dans la colonne du deuxième prénom.


Pouvez-vous me montrer un exemple de ce que vous voulez dire?


Veuillez lire pour quelques conseils sur l'amélioration de votre question.


Et si le nom est deux prénoms. "Sally Rae". C'est peut-être ce que le soulignement est destiné à transmettre. Que la 2e partie n'est pas un deuxième prénom, mais plutôt la 2e partie du prénom. Qu'en est-il de "Jo Ann" ... son prénom est "Jo Ann" ... pas "Jo".


3 Réponses :


3
votes

Ajouter la fonction Remplacer la fonction Inline:

 SELECT 
    [first name]
    ,  SUBSTRING([first name], 1,
                      CASE WHEN SUBSTRING(REVERSE(REPLACE([first name], '_', ' ')), 2, 1) = ' '
                           THEN CHARINDEX(' ', REPLACE([first name], '_', ' ')) - 1
                           ELSE LEN([first name])
                      END) AS FirstName ,
            CASE WHEN SUBSTRING(REVERSE(REPLACE([first name], '_', ' ')), 2, 1) = ' '
                 THEN SUBSTRING(REPLACE([first name], '_', ' '), LEN([first name]), 1)
                 ELSE NULL
            END AS MiddleName
    ,   [Last Name]

    FROM nametable


1 commentaires

Je reçois toujours le soulignement dans le prénom.



3
votes

L'exemple suivant utilise deux code> code> expressions em> pour séparer une colonne en deux. Il utilise une fonctionnalité de SUBSTRIND code>: Aucune erreur n'est relevée si la longueur spécifiée dépasse la longueur de la chaîne d'entrée.

Notez que les données d'échantillonnage ne sont pas une image des données, mais des données utiles . P>

declare @Samples as Table ( Name VarChar(20) );

insert into @Samples ( Name ) values
  ( 'Billy' ), ( 'Billy Bob' ), ( 'Billy_Joe' ), ( 'Edgar_7' ),
  ( '_' ), ( 'X_' ), ( '_Y' ), ( '' );

select Name,
  case
    when CharIndex( '_', Name ) > 0 then Left( Name, CharIndex( '_', Name ) - 1 )
    else Name end as FirstName,
  case
    when CharIndex( '_', Name ) > 0 then Substring( Name, CharIndex( '_', Name ) + 1, 20 )
    else NULL end as MiddleName
  from @Samples;


0 commentaires

0
votes

Grâce aux exemples de données fournies par @habo , vous pouvez essayer cela aussi:

SELECT L.Name,
       L.FirstName,
       CASE L.MiddleName WHEN '' THEN NULL ELSE L.MiddleName END AS MiddleName
FROM
(
    SELECT P.Name,
           REPLACE(SUBSTRING(P.UnderscoredName, 1, P.UnderscoreIndex), '_', '') AS FirstName,
           REPLACE(SUBSTRING(P.UnderscoredName, P.UnderscoreIndex, LEN(P.UnderscoredName) - P.UnderscoreIndex + 1),'_','') AS MiddleName
    FROM
    (
        SELECT K.Name,
               K.UnderscoredName,
               CHARINDEX('_', K.UnderscoredName) AS UnderscoreIndex
        FROM
        (
            SELECT Name,
                   REPLACE(CASE WHEN Name LIKE N'%[_]%' THEN Name ELSE Name + '_' END,' ','_') AS UnderscoredName
            FROM @Samples
        ) AS K
    ) AS P
) AS L;


4 commentaires

Votre solution ne produit pas null pour le deuxième prénom quand aucun n'est présent. La photo de l'OP des données montre NULLS. (Ma réponse ne produit pas de nulles dans certains cas, par exemple 'x _' , mais j'ai inclus divers cas de bord dans mes données d'échantillonnage pour démontrer ce qui se passe dans les cas non spécifiés par l'OP.) En tant que règle entier Les opérations sont plus efficaces que les opérations de chaîne. Ajout d'un soulignement à une chaîne puis en utilisant remplacer pour le supprimer lorsque vous pourriez simplement soustraire 1 de la longueur est surchargée.


Et remplacer est un marteau plus gros que nécessaire. Essayez d'ajouter '0_1_2' en entrée et en comparant les résultats. Certes, l'OP n'a jamais déclaré que 0 ou 1 trains de soulignement serait présent, mais .... De string_split : "Les rangées de sortie peuvent être dans n'importe quel ordre. La commande n'est pas garantie de correspondre à l'ordre des substrings de la chaîne d'entrée."


@Habo merci pour vos grands commentaires. J'ai mis à jour ma réponse et maintenant il retourne null pour le Middlename. À propos de plusieurs problèmes de soulignement que vous avez mentionnés, dans ce cas, la zone problématique n'a pas déclaré ce problème, nous devons donc savoir ce qui devrait arriver dans ce cas. Comme nous n'avons pas d'image claire à ce sujet, alors je pense que nous pourrions simplement l'ignorer. À propos du problème de commande de la fonction string_split, vous avez raison, comment j'avais déjà "partidex" qui m'aide à commander la sortie de bonne manière, mais j'ai supprimé cette requête, car je l'ai trouvé inutile.


@Habo L'atmosphère de partage des connaissances de Stackoverflow est incroyable et j'adore vraiment de parler avec des professionnels comme vous autour d'un problème. Merci et merci Stackoverflow