Wie teile ich die Namenszeichenfolge in MySQL?

103

Wie teile ich die Namenszeichenfolge in MySQL?

Z.B:

name
-----
Sachin ramesh tendulkar
Rahul dravid

Teilen Sie den Namen wie folgt auf firstname,middlename,lastname:

firstname   middlename    lastname
---------  ------------   ------------
sachin     ramesh         tendulkar
rahul      dravid
Madhav
quelle
4
Wenn Ihre Tabellen richtig normalisiert sind, haben Sie kein Problem damit. Sie müssen die Werte nicht teilen.
John Woo
2
@JW. Leider sind insbesondere Namen eine schwierige Frage. kalzumeus.com/2010/06/17/…
Matt Ball
1
@ Madhav Wenn eine der Antworten Ihre Frage gelöst hat, klicken Sie auf gelöst ... Hinweis Hinweis;)
Jesse C

Antworten:

181

Ich habe diese Antwort in zwei (2) Methoden unterteilt. Bei der ersten Methode wird das Feld für den vollständigen Namen in Vor-, Mittel- und Nachnamen unterteilt. Der zweite Vorname wird als NULL angezeigt, wenn kein zweiter Vorname vorhanden ist.

SELECT
   SUBSTRING_INDEX(SUBSTRING_INDEX(fullname, ' ', 1), ' ', -1) AS first_name,
   If(  length(fullname) - length(replace(fullname, ' ', ''))>1,  
       SUBSTRING_INDEX(SUBSTRING_INDEX(fullname, ' ', 2), ' ', -1) ,NULL) 
           as middle_name,
   SUBSTRING_INDEX(SUBSTRING_INDEX(fullname, ' ', 3), ' ', -1) AS last_name
FROM registeredusers

Diese zweite Methode betrachtet den zweiten Vornamen als Teil des Nachnamens. Wir werden nur eine Spalte mit Vor- und Nachnamen aus Ihrem Feld für den vollständigen Namen auswählen.

SELECT
   SUBSTRING_INDEX(SUBSTRING_INDEX(fullname, ' ', 1), ' ', -1) AS first_name,
    TRIM( SUBSTR(fullname, LOCATE(' ', fullname)) ) AS last_name
FROM registeredusers

Es gibt eine Menge cooler Dinge, die Sie mit substr, locate, substring_index usw. tun können. Überprüfen Sie das Handbuch auf echte Verwirrung. http://dev.mysql.com/doc/refman/5.0/en/string-functions.html

Jesse C.
quelle
6
Meine Güte, diese Informationen haben mich gerade dazu gebracht, mich mit MySQL-Pro-Fähigkeiten super menschlich zu fühlen. Ich habe die PHP-Verarbeitung vollständig entfernt und 100 Logikzeilen in einer einzigen Abfrage verarbeitet. Das ist großartig!
TeaCupApp
1
Wirklich nett. Hat genau das getan, was ich brauchte und wahrscheinlich das Problemproblem des Fragestellers besser gelöst, als er es wünschte, da bei zwei Wörtern nur Vor- und Nachname gesetzt werden, nicht Vorname und Zwischenname.
Jānis Gruzis
Die erste Methode hat mir sehr geholfen. Das einzige Problem, das ich sah, war, dass ein Nachname "St. George" als zweiter Vorname "St." aufgegriffen wurde.
Joe M.
1
Hallo Sir, ich weiß, dass dies ein alter Thread ist. Wie wäre es, wenn die Person einen Nebenstellennamen hat?
Trafalgar D Law
1
@TrafalgarDLaw Ich habe oben eine Lösung gepostet. - stackoverflow.com/a/44802256/3542883
Junior
22

Nun, nichts, was ich verwendet habe, hat funktioniert, also habe ich beschlossen, eine wirklich einfache Split-Funktion zu erstellen. Ich hoffe, es hilft:

DECLARE inipos INTEGER;
DECLARE endpos INTEGER;
DECLARE maxlen INTEGER;
DECLARE item VARCHAR(100);
DECLARE delim VARCHAR(1);

SET delim = '|';
SET inipos = 1;
SET fullstr = CONCAT(fullstr, delim);
SET maxlen = LENGTH(fullstr);

REPEAT
    SET endpos = LOCATE(delim, fullstr, inipos);
    SET item =  SUBSTR(fullstr, inipos, endpos - inipos);

    IF item <> '' AND item IS NOT NULL THEN           
        USE_THE_ITEM_STRING;
    END IF;
    SET inipos = endpos + 1;
UNTIL inipos >= maxlen END REPEAT;
Jonathan
quelle
18

Hier ist die Split-Funktion, die ich benutze:

--
-- split function
--    s   : string to split
--    del : delimiter
--    i   : index requested
--

DROP FUNCTION IF EXISTS SPLIT_STRING;

DELIMITER $

CREATE FUNCTION 
   SPLIT_STRING ( s VARCHAR(1024) , del CHAR(1) , i INT)
   RETURNS VARCHAR(1024)
   DETERMINISTIC -- always returns same results for same input parameters
    BEGIN

        DECLARE n INT ;

        -- get max number of items
        SET n = LENGTH(s) - LENGTH(REPLACE(s, del, '')) + 1;

        IF i > n THEN
            RETURN NULL ;
        ELSE
            RETURN SUBSTRING_INDEX(SUBSTRING_INDEX(s, del, i) , del , -1 ) ;        
        END IF;

    END
$

DELIMITER ;


SET @agg = "G1;G2;G3;G4;" ;

SELECT SPLIT_STRING(@agg,';',1) ;
SELECT SPLIT_STRING(@agg,';',2) ;
SELECT SPLIT_STRING(@agg,';',3) ;
SELECT SPLIT_STRING(@agg,';',4) ;
SELECT SPLIT_STRING(@agg,';',5) ;
SELECT SPLIT_STRING(@agg,';',6) ;
Olivier Delrieu
quelle
Dies funktionierte gut für mich und verursachte keine Endlosschleife wie akzeptierte Antwort (nicht klar warum) - aber es funktionierte nicht mit Leerzeichen als Trennzeichen. Wenn Sie darauf stoßen, besuchen Sie stattdessen stackoverflow.com/questions/2696884/… .
Max
15

In MySQL gibt es keine Funktion zum Teilen von Zeichenfolgen. Sie müssen also Ihre eigene Funktion erstellen. Das wird dir helfen. Weitere Details unter diesem Link .

Funktion:

CREATE FUNCTION SPLIT_STR(
  x VARCHAR(255),
  delim VARCHAR(12),
  pos INT
)
RETURNS VARCHAR(255)
RETURN REPLACE(SUBSTRING(SUBSTRING_INDEX(x, delim, pos),
       LENGTH(SUBSTRING_INDEX(x, delim, pos -1)) + 1),
       delim, '');

Verwendung:

SELECT SPLIT_STR(string, delimiter, position)

Beispiel:

SELECT SPLIT_STR('a|bb|ccc|dd', '|', 3) as third;

+-------+
| third |
+-------+
| ccc   |
+-------+
Rahul Chipad
quelle
Dies ist die bisher beste Antwort
Hydrocat
Beste Antwort, ich benutze es definitiv 👍✨
Rizki Noor Hidayat Wijaya
11

Sie können bewlo eins auch verwenden:

SELECT SUBSTRING_INDEX(Name, ' ', 1) AS fname,
SUBSTRING_INDEX(SUBSTRING_INDEX(Name,' ', 2), ' ',-1) AS mname,
SUBSTRING_INDEX(Name, ' ', -1) as lname FROM mytable;
user2001117
quelle
Das hat bei mir funktioniert. Ich habe das Gefühl, dass es eine schlechte Praxis ist, aber ich habe dieselbe Abfrage ausgeführt, bei der meine Fallaussage dupliziert wurde, und festgestellt, dass dieser Ansatz doppelt so schnell ist. Vielen Dank.
jDub9
3
select (case when locate('(', LocationName) = 0 
        then 
            horse_name
        else 
           left(LocationName, locate('(', LocationName) - 1)
       end) as Country            
from   tblcountry;
Farookh Mansuri
quelle
2

Um den Rest der Zeichenfolge nach der zweiten Instanz des Leerzeichenbegrenzers abzurufen

SELECT
   SUBSTRING_INDEX(SUBSTRING_INDEX('Sachin ramesh tendulkar', ' ', 1), ' ', -1) AS first_name, 
       SUBSTRING_INDEX(SUBSTRING_INDEX('Sachin ramesh tendulkar', ' ', 2), ' ', -1) 
           AS middle_name,
   SUBSTRING('Sachin ramesh tendulkar',LENGTH(SUBSTRING_INDEX('Sachin ramesh tendulkar', ' ', 2))+1) AS last_name
Patnaidu Landa
quelle
2
SELECT
    p.fullname AS 'Fullname',
    SUBSTRING_INDEX(p.fullname, ' ', 1) AS 'Firstname',
    SUBSTRING(p.fullname, LOCATE(' ',p.fullname), 
        (LENGTH(p.fullname) - (LENGTH(SUBSTRING_INDEX(p.fullname, ' ', 1)) + LENGTH(SUBSTRING_INDEX(p.fullname, ' ', -1))))
    ) AS 'Middlename',
    SUBSTRING_INDEX(p.fullname, ' ', -1) AS 'Lastname',
    (LENGTH(p.fullname) - LENGTH(REPLACE(p.fullname, ' ', '')) + 1) AS 'Name Qt'
FROM people AS p
LIMIT 100; 

Erklären:

Das Suchen von Vor- und Nachnamen ist einfach. Sie müssen nur die Funktion SUBSTR_INDEX verwenden. Magic geschieht im mittleren Namen, wobei SUBSTR mit Locate verwendet wurde, um die erste Leerzeichenposition und die Länge des vollständigen Namens zu finden - (LENGTH Vorname + LENGTH Nachname), um den gesamten Zwischennamen abzurufen.

Beachten Sie, dass die LÄNGE von Vor- und Nachname mit SUBSTR_INDEX berechnet wurde

Junior
quelle
2
concat(upper(substring(substring_index(NAME, ' ', 1) FROM 1 FOR 1)), lower(substring(substring_index(NAME, ' ', 1) FROM 2 FOR length(substring_index(NAME, ' ', 1))))) AS fname,
CASE 
WHEN length(substring_index(substring_index(NAME, ' ', 2), ' ', -1)) > 2 THEN 
  concat(upper(substring(substring_index(substring_index(NAME, ' ', 2), ' ', -1) FROM 1 FOR 1)), lower(substring(substring_index(substring_index(f.nome, ' ', 2), ' ', -1) FROM 2 FOR length(substring_index(substring_index(f.nome, ' ', 2), ' ', -1)))))
  ELSE 
  CASE 
  WHEN length(substring_index(substring_index(f.nome, ' ', 3), ' ', -1)) > 2 THEN 
    concat(upper(substring(substring_index(substring_index(f.nome, ' ', 3), ' ', -1) FROM 1 FOR 1)), lower(substring(substring_index(substring_index(f.nome, ' ', 3), ' ', -1) FROM 2 FOR length(substring_index(substring_index(f.nome, ' ', 3), ' ', -1)))))
  END 
END 
AS mname
Paulo Roberto Rodrigues
quelle
1
CREATE DEFINER=`root`@`localhost` FUNCTION `getNameInitials`(`fullname` VARCHAR(500), `separator` VARCHAR(1)) RETURNS varchar(70) CHARSET latin1
    DETERMINISTIC
BEGIN
DECLARE `result` VARCHAR(500) DEFAULT '';
DECLARE `position` TINYINT;



SET `fullname` = TRIM(`fullname`);

SET `position` = LOCATE(`separator`, `fullname`);

IF NOT `position`
THEN RETURN LEFT(`fullname`,1);
END IF;

SET `fullname` = CONCAT(`fullname`,`separator`);
SET `result` = LEFT(`fullname`, 1);

cycle: LOOP
    SET `fullname` = SUBSTR(`fullname`, `position` + 1);
    SET `position` = LOCATE(`separator`, `fullname`);

    IF NOT `position` OR NOT LENGTH(`fullname`)
    THEN LEAVE cycle;
    END IF;

    SET `result` = CONCAT(`result`,LEFT(`fullname`, 1));
   -- SET `result` = CONCAT_WS(`separator`, `result`, `buffer`);
END LOOP cycle;

RETURN upper(`result`);
END

1. Führen Sie diese Funktion in MySQL aus. 2. Dadurch wird eine Funktion erstellt. Jetzt können Sie diese Funktion überall verwenden.

 SELECT `getNameInitials`('Kaleem Ul Hassan', ' ') AS `NameInitials`;

3. Der obige erste Parameter getNameInitails ist eine Zeichenfolge, die Sie filtern möchten, und der zweite ist das Zuschauerzeichen, nach dem Sie Ihre Zeichenfolge trennen möchten. 4. Im obigen Beispiel ist 'Kaleem Ul Hassan' der Name und ich möchte Initialen erhalten und mein Trennzeichen ist Leerzeichen ''.

user3867306
quelle
1

Wir haben den Wert des Kursnamens und des Kapitelnamens in einer Spalte ChapterName gespeichert.

Wert gespeichert wie: "JAVA: Polymorphismus"

Sie müssen CourseName: JAVA und ChapterName: Polymorphism abrufen

Unten finden Sie die abzurufende SQL-Auswahlabfrage.

       SELECT   
          SUBSTRING_INDEX(SUBSTRING_INDEX(ChapterName, ' ', 1), ' ', -1) AS 
       CourseName,

       REPLACE(TRIM(SUBSTR(ChapterName, LOCATE(':', ChapterName)) ),':','') AS 
       ChapterName
       FROM Courses where `id`=1;

Bitte lassen Sie mich wissen, wenn Sie Fragen dazu haben.

Bikash Ranjan
quelle
0

So rufen Sie den Rest der Zeichenfolge nach der zweiten Instanz des Leerzeichenbegrenzers ab:

SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(MsgRest, ' ', 1), ' ', -1) AS EMailID
,  SUBSTRING_INDEX(SUBSTRING_INDEX(MsgRest, ' ', 2), ' ', -1) AS DOB
,  IF(
    LOCATE(' ', `MsgRest`) > 0,
    TRIM(SUBSTRING(SUBSTRING(`MsgRest`, LOCATE(' ', `MsgRest`) +1), 
         LOCATE(' ', SUBSTRING(`MsgRest`, LOCATE(' ', `MsgRest`) +1)) +1)),
    NULL
) AS Person
FROM inbox
Biz Web
quelle
0

Sie können das common_schema und die tokenizeFunktion verwenden. Weitere Informationen hierzu finden Sie unter den Links. Ihr Code würde am Ende wie folgt aussehen:

call tokenize(name, ' ');

Beachten Sie jedoch, dass ein Leerzeichen kein zuverlässiges Trennzeichen für Vor- und Nachnamen ist. In Spanien ist es beispielsweise üblich, zwei Nachnamen zu haben.

ToBe_HH
quelle
0

DELIMITER $$

DROP FUNCTION IF EXISTS `split_name`$$

CREATE FUNCTION split_name (p_fullname TEXT, p_part INTEGER)
RETURNS TEXT
    READS SQL DATA
BEGIN
    DECLARE v_words INT UNSIGNED;
    DECLARE v_name TEXT;

    SET p_fullname=RTRIM(LTRIM(p_fullname));

    SET v_words=(SELECT SUM(LENGTH(p_fullname) - LENGTH(REPLACE(p_fullname, ' ', ''))+1));

    IF v_words=1 THEN 
        IF p_part=1 THEN
            SET v_name=p_fullname;
        ELSEIF p_part=2 THEN
            SET v_name=NULL;
        ELSEIF p_part=3 THEN
            SET v_name=NULL;
        ELSE
            SET v_name=NULL;
        END IF; 
    ELSEIF v_words=2 THEN 
        IF p_part=1 THEN
            SET v_name=SUBSTRING(p_fullname, 1, LOCATE(' ', p_fullname) - 1);
        ELSEIF p_part=2 THEN
            SET v_name=SUBSTRING(p_fullname, LOCATE(' ', p_fullname) + 1);
        ELSEIF p_part=3 THEN
            SET v_name=NULL;
        ELSE
            SET v_name=NULL;
        END IF; 
    ELSEIF v_words=3 THEN 
        IF p_part=1 THEN
            SET v_name=SUBSTRING(p_fullname, 1, LOCATE(' ', p_fullname) - 1);
        ELSEIF p_part=2 THEN
            SET p_fullname=SUBSTRING(p_fullname, LOCATE(' ', p_fullname) + 1);
            SET v_name=SUBSTRING(p_fullname, 1, LOCATE(' ', p_fullname) - 1);
        ELSEIF p_part=3 THEN
            SET p_fullname=REVERSE (SUBSTRING(p_fullname, LOCATE(' ', p_fullname) + 1));
            SET p_fullname=SUBSTRING(p_fullname, 1, LOCATE(' ', p_fullname) - 1);
            SET v_name=REVERSE(p_fullname);
        ELSE
            SET v_name=NULL;
        END IF; 
    ELSEIF v_words>3 THEN 
        IF p_part=1 THEN
            SET v_name=SUBSTRING(p_fullname, 1, LOCATE(' ', p_fullname) - 1);
        ELSEIF p_part=2 THEN
            SET p_fullname=REVERSE(SUBSTRING(p_fullname, LOCATE(' ', p_fullname) + 1));
            SET p_fullname=SUBSTRING(p_fullname, LOCATE(' ', p_fullname,SUBSTRING_INDEX(p_fullname,' ',1)+1) + 1);
            SET v_name=REVERSE(p_fullname);
        ELSEIF p_part=3 THEN
            SET p_fullname=REVERSE (SUBSTRING(p_fullname, LOCATE(' ', p_fullname) + 1));
            SET p_fullname=SUBSTRING(p_fullname, 1, LOCATE(' ', p_fullname) - 1);
            SET v_name=REVERSE(p_fullname);
        ELSE
            SET v_name=NULL;
        END IF;
    ELSE
        SET v_name=NULL;
    END IF;
 RETURN v_name; 
END;

SELECT split_name('Md. Obaidul Haque Sarker',1) AS first_name,
split_name('Md. Obaidul Haque Sarker',2) AS middle_name,
split_name('Md. Obaidul Haque Sarker',3) AS last_name
Md. Obaidul Haque Sarker
quelle
0

Erstellen Sie zuerst die folgende Prozedur:

CREATE DEFINER=`root`@`%` PROCEDURE `sp_split`(str nvarchar(6500), dilimiter varchar(15), tmp_name varchar(50))
BEGIN

    declare end_index   int;
    declare part        nvarchar(6500);
    declare remain_len  int;

    set end_index      = INSTR(str, dilimiter);

    while(end_index   != 0) do

        /* Split a part */
        set part       = SUBSTRING(str, 1, end_index - 1);

        /* insert record to temp table */
        call `sp_split_insert`(tmp_name, part);

        set remain_len = length(str) - end_index;
        set str = substring(str, end_index + 1, remain_len);

        set end_index  = INSTR(str, dilimiter);

    end while;

    if(length(str) > 0) then

        /* insert record to temp table */
        call `sp_split_insert`(tmp_name, str);

    end if;

END

Danach erstellen Sie die Prozedur wie folgt:

CREATE DEFINER=`root`@`%` PROCEDURE `sp_split_insert`(tb_name varchar(255), tb_value nvarchar(6500))
BEGIN
    SET @sql = CONCAT('Insert Into ', tb_name,'(item) Values(?)'); 
    PREPARE s1 from @sql;
    SET @paramA = tb_value;
    EXECUTE s1 USING @paramA;
END

Wie Test anrufen

CREATE DEFINER=`root`@`%` PROCEDURE `test_split`(test_text nvarchar(255))
BEGIN

    create temporary table if not exists tb_search
        (
            item nvarchar(6500)
        );

    call sp_split(test_split, ',', 'tb_search');

    select * from tb_search where length(trim(item)) > 0;

    drop table tb_search;

END


call `test_split`('Apple,Banana,Mengo');
Pa Julieta
quelle
0

Kombinieren Sie hier einige Antworten, um einen SP zu erstellen, der die Teile der Zeichenfolge zurückgibt.

drop procedure if exists SplitStr;
DELIMITER ;;
CREATE PROCEDURE `SplitStr`(IN Str VARCHAR(2000), IN Delim VARCHAR(1))  
    BEGIN
        DECLARE inipos INT;
        DECLARE endpos INT;
        DECLARE maxlen INT;
        DECLARE fullstr VARCHAR(2000);
        DECLARE item VARCHAR(2000);
        create temporary table if not exists tb_split
        (
            item varchar(2000)
        );



        SET inipos = 1;
        SET fullstr = CONCAT(Str, delim);
        SET maxlen = LENGTH(fullstr);

        REPEAT
            SET endpos = LOCATE(delim, fullstr, inipos);
            SET item =  SUBSTR(fullstr, inipos, endpos - inipos);

            IF item <> '' AND item IS NOT NULL THEN           
                insert into tb_split values(item);
            END IF;
            SET inipos = endpos + 1;
        UNTIL inipos >= maxlen END REPEAT;

        SELECT * from tb_split;
        drop table tb_split;
    END;;
DELIMITER ;
singhspk
quelle