Bagaimana cara membagi string nama di mysql?

103

Bagaimana cara membagi string nama di mysql?

Misalnya:

name
-----
Sachin ramesh tendulkar
Rahul dravid

Pisahkan namanya seperti firstname,middlename,lastname:

firstname   middlename    lastname
---------  ------------   ------------
sachin     ramesh         tendulkar
rahul      dravid
Madhav
sumber
4
ketika tabel Anda dinormalisasi dengan benar, Anda tidak punya masalah dalam hal ini. Anda tidak perlu membagi nilainya.
John Woo
2
@JW. sayangnya, nama-nama khususnya adalah nama yang sulit. kalzumeus.com/2010/06/17/…
Matt Ball
1
@Madhav Jika ada jawaban yang memecahkan pertanyaan Anda, klik diselesaikan ... petunjuk petunjuk;)
Jesse C

Jawaban:

181

Saya telah memisahkan jawaban ini menjadi dua (2) metode. Metode pertama akan memisahkan bidang nama lengkap Anda menjadi nama depan, tengah, dan belakang. Nama tengah akan ditampilkan sebagai NULL jika tidak ada nama tengah.

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

Metode kedua ini menganggap nama tengah sebagai bagian dari nama belakang. Kami hanya akan memilih kolom nama depan dan nama belakang dari kolom nama lengkap Anda.

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

Ada banyak hal keren yang dapat Anda lakukan dengan substr, lokasi, substring_index, dll. Periksa manual untuk kebingungan yang sebenarnya. http://dev.mysql.com/doc/refman/5.0/en/string-functions.html

Jesse C
sumber
6
Astaga, intel baru saja membuatku merasa super manusia dengan kemampuan mysql pro. Saya telah sepenuhnya menghapus pemrosesan PHP dan mengubah 100 baris logika dalam satu kueri. Ini luar biasa!
TeaCupApp
1
Benar-benar bagus. Melakukan persis apa yang saya butuhkan dan mungkin memecahkan acara masalah penanya lebih baik daripada yang dia inginkan, karena dalam kasus dua kata hanya nama depan dan nama belakang yang disetel bukan nama depan dan nama tengah.
Jānis Gruzis
Metode pertama sangat membantu saya. Satu-satunya masalah yang saya lihat adalah nama belakang "St. George" diambil sebagai nama tengah "St.".
Joe M.
1
Halo Pak, saya tahu ini adalah utas lama. Bagaimana jika orang tersebut memiliki nama ekstensi?
Trafalgar D Law
1
@TrafalgarDLaw Saya memposting solusi di atas. - stackoverflow.com/a/44802256/3542883
Junior
22

Nah, tidak ada yang saya gunakan yang berhasil, jadi saya memutuskan untuk membuat fungsi split sederhana yang sebenarnya, semoga ini membantu:

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
sumber
18

Berikut adalah fungsi split yang saya gunakan:

--
-- 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
sumber
Ini berfungsi dengan baik untuk saya, dan tidak menyebabkan putaran tak terbatas seperti jawaban yang diterima (tidak jelas mengapa) - tetapi tidak berfungsi dengan spasi sebagai pemisah. Bagi siapa pun yang tersandung pada hal ini - lihat stackoverflow.com/questions/2696884/… sebagai gantinya.
Maksimal
15

Tidak ada fungsi pemisahan string di MySQL. jadi Anda harus membuat fungsi Anda sendiri. Ini akan membantumu. Lebih detail di tautan ini .

Fungsi:

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

Pemakaian:

SELECT SPLIT_STR(string, delimiter, position)

Contoh:

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

+-------+
| third |
+-------+
| ccc   |
+-------+
Rahul Chipad
sumber
Ini adalah jawaban terbaik sejauh ini
Hydrocat
jawaban terbaik, saya pasti menggunakannya 👍✨
Rizki Noor Hidayat Wijaya
11

Anda juga dapat menggunakan bewlo one:

SELECT SUBSTRING_INDEX(Name, ' ', 1) AS fname,
SUBSTRING_INDEX(SUBSTRING_INDEX(Name,' ', 2), ' ',-1) AS mname,
SUBSTRING_INDEX(Name, ' ', -1) as lname FROM mytable;
pengguna2001117
sumber
Ini berhasil untuk saya. Saya merasa ini praktik yang buruk, tetapi saya menjalankan kueri yang sama yang menduplikasi pernyataan kasus saya dan melihat bahwa pendekatan ini dua kali lebih cepat. Terima kasih.
jDub9
3
select (case when locate('(', LocationName) = 0 
        then 
            horse_name
        else 
           left(LocationName, locate('(', LocationName) - 1)
       end) as Country            
from   tblcountry;
Farookh Mansuri
sumber
2

Untuk mendapatkan sisa string setelah contoh kedua dari pemisah spasi

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

Menjelaskan:

Menemukan nama depan dan nama belakang itu mudah, Anda hanya perlu menggunakan fungsi SUBSTR_INDEX Keajaiban terjadi di middlename, di mana digunakan SUBSTR dengan Locate untuk menemukan posisi spasi pertama dan PANJANG nama lengkap - (LENGTH firstname + LENGTH lastname) untuk mendapatkan semua nama tengah.

Perhatikan bahwa LENGTH nama depan dan nama belakang dihitung menggunakan SUBSTR_INDEX

Muda
sumber
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
sumber
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. Jalankan fungsi ini di mysql. 2. ini akan membuat sebuah fungsi. Sekarang Anda dapat menggunakan fungsi ini di mana pun Anda mau.

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

3. Parameter pertama getNameInitails di atas adalah string yang ingin Anda filter dan kedua adalah karakter penonton yang Anda ingin pisahkan stringnya. 4. Dalam contoh di atas 'Kaleem Ul Hassan' adalah nama dan saya ingin mendapatkan inisial dan pemisah saya adalah spasi ''.

pengguna3867306
sumber
1

Kami telah menyimpan nilai dari course Name dan chapter name dalam satu kolom ChapterName.

Nilai disimpan seperti: "JAVA: Polymorphism"

Anda perlu mengambil CourseName: JAVA dan ChapterName: Polymorphism

Di bawah ini adalah kueri pemilihan SQL untuk diambil.

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

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

Tolong beritahu saya jika ada pertanyaan tentang ini.

Bikash Ranjan
sumber
0

Untuk mendapatkan sisa string setelah contoh kedua dari pemisah spasi:

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

Anda bisa menggunakan common_schema dan menggunakan tokenizefungsinya. Untuk informasi lebih lanjut tentang ini, ikuti tautannya. Kode Anda akan berakhir seperti:

call tokenize(name, ' ');

Namun, ketahuilah bahwa spasi bukanlah pemisah yang dapat diandalkan untuk nama depan dan belakang. Misalnya Di Spanyol, biasanya memiliki dua nama belakang.

ToBe_HH
sumber
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
sumber
0

Prosedur Buat Pertama seperti Di Bawah Ini:

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

Setelah itu buat prosedur seperti di bawah ini:

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

Bagaimana tes panggilan

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

Menggabungkan beberapa jawaban di sini untuk membuat SP yang mengembalikan bagian-bagian string.

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
sumber