У мене є поле таблиці, membername
яке містить і прізвище, і ім’я користувачів. Чи можна розділити ці в 2 -х полів memberfirst
, memberlast
?
Усі записи мають такий формат "Прізвище ім'я" (без лапок та проміжку між ними).
У мене є поле таблиці, membername
яке містить і прізвище, і ім’я користувачів. Чи можна розділити ці в 2 -х полів memberfirst
, memberlast
?
Усі записи мають такий формат "Прізвище ім'я" (без лапок та проміжку між ними).
Відповіді:
На жаль, MySQL не має функції розділеного рядка. Однак ви можете створити для цього функцію, визначену користувачем , таку, як описана в наступній статті:
За допомогою цієї функції:
DELIMITER $$
CREATE FUNCTION SPLIT_STR(
x VARCHAR(255),
delim VARCHAR(12),
pos INT
)
RETURNS VARCHAR(255) DETERMINISTIC
BEGIN
RETURN REPLACE(SUBSTRING(SUBSTRING_INDEX(x, delim, pos),
LENGTH(SUBSTRING_INDEX(x, delim, pos -1)) + 1),
delim, '');
END$$
DELIMITER ;
ви зможете побудувати свій запит наступним чином:
SELECT SPLIT_STR(membername, ' ', 1) as memberfirst,
SPLIT_STR(membername, ' ', 2) as memberlast
FROM users;
Якщо ви не бажаєте використовувати функцію, визначену користувачем, і ви не заперечуєте, щоб запит був дещо докладнішим, ви також можете зробити наступне:
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(membername, ' ', 1), ' ', -1) as memberfirst,
SUBSTRING_INDEX(SUBSTRING_INDEX(membername, ' ', 2), ' ', -1) as memberlast
FROM users;
LENGTH
безпечне ваше використання багатобайтових? "LENGTH (str): повертає довжину рядка str, вимірюється в байтах. Багатобайтовий символ вважається кратним байтом. Це означає, що для рядка, що містить п'ять 2-байтних символів, LENGTH () повертає 10, тоді як CHAR_LENGTH () повертається 5. "
SELECT варіант (не створює визначену користувачем функцію):
SELECT IF(
LOCATE(' ', `membername`) > 0,
SUBSTRING(`membername`, 1, LOCATE(' ', `membername`) - 1),
`membername`
) AS memberfirst,
IF(
LOCATE(' ', `membername`) > 0,
SUBSTRING(`membername`, LOCATE(' ', `membername`) + 1),
NULL
) AS memberlast
FROM `user`;
Цей підхід також забезпечує:
ОНОВЛЕНА версія буде:
UPDATE `user` SET
`memberfirst` = IF(
LOCATE(' ', `membername`) > 0,
SUBSTRING(`membername`, 1, LOCATE(' ', `membername`) - 1),
`membername`
),
`memberlast` = IF(
LOCATE(' ', `membername`) > 0,
SUBSTRING(`membername`, LOCATE(' ', `membername`) + 1),
NULL
);
Здається, що відповіді над складною чи не суворою відповіддю на конкретне питання.
Я думаю, проста відповідь - це наступний запит:
SELECT
SUBSTRING_INDEX(`membername`, ' ', 1) AS `memberfirst`,
SUBSTRING_INDEX(`membername`, ' ', -1) AS `memberlast`
;
Я вважаю, що не потрібно мати справу з більш ніж двома словами назви в цій конкретній ситуації. Якщо ви хочете зробити це правильно, розщеплення може бути дуже важким або навіть неможливим:
У правильно розробленій базі даних імена людини повинні зберігатися як у частинах, так і в цілому. Звичайно, це не завжди можливо.
Якщо ваш план полягає у виконанні цього запиту, будь ласка , не робіть цього (a) . Серйозно, це вбивця продуктивності. Можливо, трапляються ситуації, коли вам не важлива ефективність (наприклад, разові міграційні завдання для розділення полів, що дозволяють покращити ефективність у майбутньому), але якщо ви робите це регулярно для чогось іншого, крім бази даних «Міккі-миша», витрачаєш ресурси.
Якщо вам коли-небудь доведеться обробляти лише частину стовпця якимось чином, ваш дизайн БД є помилковим. Це може добре працювати з домашньою адресною книгою чи програмою рецептів або будь-якою з безлічі інших невеликих баз даних, але це не буде масштабуватися до "реальних" систем.
Зберігайте компоненти імені в окремих стовпцях. Майже незмінно набагато швидше з'єднувати стовпці разом з простим конкатенацією (коли вам потрібно повне ім’я), ніж це розділити їх на розріз пошуку символів.
Якщо з якоїсь причини ви не можете розділити поле, принаймні поставте в додаткові стовпці та використовуйте тригер вставлення / оновлення, щоб заповнити їх. Хоча це не 3NF, це гарантуватиме, що дані все ще є послідовними та значно прискорить ваші запити. Ви також можете переконатися, що додаткові стовпці мають нижній регістр (та індексовано, якщо ви шукаєте в них) одночасно, щоб не довелося спіткнутися з проблемами справи.
І якщо ви навіть не можете додати стовпці та тригери, будьте в курсі (та повідомте свого клієнта, якщо це для клієнта), що це не масштабується.
(a) Звичайно, якщо ваш намір полягає в тому, щоб використовувати цей запит для виправлення схеми, щоб імена розміщувались в окремих стовпцях таблиці, а не запит, я вважаю це правильним використанням. Але я повторюю: робити це в запиті не дуже добре.
використовуй це
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX( `membername` , ' ', 2 ),' ',1) AS b,
SUBSTRING_INDEX(SUBSTRING_INDEX( `membername` , ' ', -1 ),' ',2) AS c FROM `users` WHERE `userid`='1'
Не точно відповідаючи на запитання, але зіткнувшись з тією ж проблемою, я закінчився цим:
UPDATE people_exit SET last_name = SUBSTRING_INDEX(fullname,' ',-1)
UPDATE people_exit SET middle_name = TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX(fullname,last_name,1),' ',-2))
UPDATE people_exit SET middle_name = '' WHERE CHAR_LENGTH(middle_name)>3
UPDATE people_exit SET first_name = SUBSTRING_INDEX(fullname,concat(middle_name,' ',last_name),1)
UPDATE people_exit SET first_name = middle_name WHERE first_name = ''
UPDATE people_exit SET middle_name = '' WHERE first_name = middle_name
У MySQL працює цей параметр:
SELECT Substring(nameandsurname, 1, Locate(' ', nameandsurname) - 1) AS
firstname,
Substring(nameandsurname, Locate(' ', nameandsurname) + 1) AS lastname
FROM emp
Єдиний випадок, коли вам може знадобитися така функція - це запит UPDATE, який змінить вашу таблицю для зберігання імені та прізвища в окремих полях.
Дизайн бази даних повинен відповідати певним правилам, а нормалізація бази даних - одна з найважливіших
У мене була стовпець, де і ім’я, і ім’я, і прізвище були в одній колоні Ім'я та прізвище були розділені комою. Код нижче працював. Немає перевірки / виправлення помилок. Просто німий розкол. Використовується phpMyAdmin для виконання оператора SQL.
UPDATE tblAuthorList SET AuthorFirst = SUBSTRING_INDEX(AuthorLast,',',-1) , AuthorLast = SUBSTRING_INDEX(AuthorLast,',',1);
Це приймає smhg звідси і curt з Last indeks даної підрядки в MySQL і поєднує їх. Це для mysql, все, що мені потрібно було, щоб отримати гідний розкол імені до прізвища прізвище прізвище з прізвищем одне слово, ім'я все перед цим єдиним словом, де ім'я може бути нульовим, 1 слово, 2 слова або більше 2 слів. Т.е.: Нуль; Мері; Мері Сміт; Мері А. Сміт; Мері Сью Еллен Сміт;
Отже, якщо ім'я - це одне слово або null, прізвище - null. Якщо ім'я> 1 слово, прізвище - це останнє слово, а ім’я - усе ім'я перед останнім словом.
Зауважте, що я вже обрізав такі речі, як Джо Сміт-молодший; Джо Сміт Еск. і так далі, вручну, що було болісно, звичайно, але це було досить мало, щоб ви хотіли переконатися, що дійсно перегляньте дані в полі імен, перш ніж вирішити, який метод використовувати.
Зауважте, що це також зменшує результат, тому ви не закінчите пробілами перед іменами або після них.
Я просто розміщую це для інших, хто може google їхній шлях тут шукаю те, що мені потрібно. Це працює, звичайно, тестуйте його за допомогою вибору спочатку.
Це разова річ, тому я не дбаю про ефективність.
SELECT TRIM(
IF(
LOCATE(' ', `name`) > 0,
LEFT(`name`, LENGTH(`name`) - LOCATE(' ', REVERSE(`name`))),
`name`
)
) AS first_name,
TRIM(
IF(
LOCATE(' ', `name`) > 0,
SUBSTRING_INDEX(`name`, ' ', -1) ,
NULL
)
) AS last_name
FROM `users`;
UPDATE `users` SET
`first_name` = TRIM(
IF(
LOCATE(' ', `name`) > 0,
LEFT(`name`, LENGTH(`name`) - LOCATE(' ', REVERSE(`name`))),
`name`
)
),
`last_name` = TRIM(
IF(
LOCATE(' ', `name`) > 0,
SUBSTRING_INDEX(`name`, ' ', -1) ,
NULL
)
);
Метод, який я використовував, щоб розділити ім'я на ім'я та прізвище, коли дані надійшли у поле ім'я. Це додасть лише останнє слово в поле прізвища, тож "Джон Філліпс Суса" буде "Джон Філліпс" ім'ям та "Суса" прізвищем. Це також дозволяє уникнути перезапису записів, які вже були виправлені.
set last_name=trim(SUBSTRING_INDEX(first_name, ' ', -1)), first_name=trim(SUBSTRING(first_name,1,length(first_name) - length(SUBSTRING_INDEX(first_name, ' ', -1)))) where list_id='$List_ID' and length(first_name)>0 and length(trim(last_name))=0
UPDATE `salary_generation_tbl` SET
`modified_by` = IF(
LOCATE('$', `other_salary_string`) > 0,
SUBSTRING(`other_salary_string`, 1, LOCATE('$', `other_salary_string`) - 1),
`other_salary_string`
),
`other_salary` = IF(
LOCATE('$', `other_salary_string`) > 0,
SUBSTRING(`other_salary_string`, LOCATE('$', `other_salary_string`) + 1),
NULL
);