2013-02-19 8 views
52

Come dividere la stringa del nome in mysql?Come dividere la stringa del nome in mysql?

Es .:

name 
----- 
Sachin ramesh tendulkar 
Rahul dravid 

Spalato il nome come firstname,middlename,lastname:

firstname middlename lastname 
--------- ------------ ------------ 
sachin  ramesh   tendulkar 
rahul  dravid 
+4

quando le tabelle sono correttamente normalizzano, don; t hanno alcun problema su questo. * Non è necessario dividere i valori. * –

+0

possibile duplicato di [Puoi dividere/esplodere un campo in una query MySQL?] (Http://stackoverflow.com/questions/471914/can-you-split-explode -a-field-in-a-mysql-query) –

+2

@JW. sfortunatamente, i nomi in particolare sono difficili. http://www.kalzumeus.com/2010/06/17/falsehoods-programmers-believe-about-names/ –

risposta

116

ho separati questa risposta in due (2) metodi. Il primo metodo separerà il tuo campo fullname in first, middle e last name. Il secondo nome verrà mostrato come NULL se non c'è un secondo nome.

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 

Questo secondo metodo considera il secondo nome come parte del cognome. Selezioneremo solo una colonna nome e cognome dal campo nome completo.

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

C'è un sacco di cose interessanti che si possono fare con substr, individuare, substring_index, ecc Controllare il manuale per alcuni vero confusione. http://dev.mysql.com/doc/refman/5.0/en/string-functions.html

+2

Accidenti a quell'intelligence mi ha fatto sentire super umano con le abilità di MySQL pro. Ho rimosso completamente l'elaborazione PHP e ho trasformato 100 righe di logica in una singola query. Questo è fantastico! – doNotCheckMyBlog

+1

Davvero bello. Ha fatto esattamente ciò di cui avevo bisogno e probabilmente ha risolto l'evento problematico degli askers meglio di quanto desiderasse, dal momento che in caso di due parole solo nome e cognome non sono impostati come firstname e middlename. –

+0

Il primo metodo mi ha aiutato molto. L'unico problema che ho visto era il cognome "St. George" preso come secondo nome "St.". –

4

È possibile utilizzare bewlo uno anche:

SELECT SUBSTRING_INDEX(Name, ' ', 1) AS fname, 
SUBSTRING_INDEX(SUBSTRING_INDEX(Name,' ', 2), ' ',-1) AS mname, 
SUBSTRING_INDEX(Name, ' ', -1) as lname FROM mytable; 
14

Beh, niente ho usato lavorato, così ho deciso di creare una vera e propria funzione split semplice, spero che aiuta:

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; 
+0

Molto buono! Funziona perfettamente. Questo è quello che stavo cercando! –

0

Per ottenere risultati resto della stringa dopo la seconda istanza del delimitatore spazio:

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 
11

Ecco la scissione funzione che uso:

-- 
-- 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) ; 
+0

Questo ha funzionato bene per me e non ha causato un ciclo infinito come risposta accettata (non chiaro perché), ma non ha funzionato con spazi bianchi come separatore. Per chiunque inciampi su questo - guarda https://stackoverflow.com/questions/2696884/split-value-from-one-field-to-two#2696901 invece. – Max

0

prima creare Procedura come qui sotto:

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 

Dopo tale procedura creare, come di seguito:

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 

Come chiamata di prova

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'); 
2

per ottenere il resto della stringa dopo la seconda istanza dello spazio delimitatore

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 
0

È possibile utilizzare il common_schema e utilizzare la funzione tokenize. Per ulteriori informazioni su questo, seguire i collegamenti.Il tuo codice sarebbe finire come:

call tokenize(name, ' ');

Tuttavia, essere consapevoli del fatto che uno spazio non è un separatore affidabile per nome e cognome. Per esempio. In Spagna è comune avere due cognomi.

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 
+0

Aggiungi una spiegazione del tuo codice. – ketan

0
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.Execute questa funzione in mysql. 2.questo creerà una funzione. Ora puoi usare questa funzione ovunque tu voglia.

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

3. Le getNameInitails sopra primo parametro è stringa che si desidera filtrare e la seconda è il carattere spettatore su cui si desidera separare voi stringa. 4. Nell'esempio sopra 'Kaleem Ul Hassan' è il nome e voglio ottenere le iniziali e il mio separatore è lo spazio ''.

1
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; 

Spiegando:

Trova nome e cognome è facile, basta usare la funzione SUBSTR_INDEX magia accade in MiddleName, in cui è stato utilizzato SUBSTR con Individuare per trovare la prima posizione dello spazio e la durata del fullname - (LENGTH firstname + LENGTH lastname) per ottenere tutto il middlename.

Nota che la lunghezza del nome e cognome sono stati calcolati usando SUBSTR_INDEX