У меня есть поле таблицы, membernameкоторое содержит как фамилии, так и имена пользователей. Можно ли разделить эти в 2 -х полей memberfirst, memberlast?
Все записи имеют формат «Имя Фамилия» (без кавычек и пробелов между ними).
«Все записи имеют формат« Имя Фамилия »(без кавычек и пробела между ними)». ... чудесно ... Пожалуйста, пожалуйста , не забывайте о людях , как я при принятии решений в базе данных. Слишком часто я получаю сайты, которые говорят мне, что моя фамилия содержит недопустимый (sic) символ ... :(
Stijn de Witt
@StijndeWitt В целом вы правы, однако похоже, что эта база данных не содержит вашего имени, по крайней мере, в официальной форме. В моей стране фамилии пишутся первыми, поэтому я тоже должен быть "размечен" в этой таблице данных. Просто посмотри на это ->
Давид Хорват
Ответы:
226
К сожалению, MySQL не поддерживает функцию разделения строк. Однако вы можете создать для этого пользовательскую функцию , например, описанную в следующей статье:
все же вы не можете использовать IN как «массив значений» из этой операции разделения?
Мигель
3
LENGTHБезопасно ли ваше использование многобайтовых файлов ? "LENGTH (str): возвращает длину строки str, измеренную в байтах. Многобайтовый символ считается как несколько байтов. Это означает, что для строки, содержащей пять 2-байтовых символов, LENGTH () возвращает 10, тогда как CHAR_LENGTH () возвращает 5.»
Erk
Это не будет работать должным образом при работе с многобайтовыми символами / utf8, как упоминал @Erk. Только простое решение с двумя операторами SUBSTRING_INDEX работает с utf8 / multibyte
Майкл
LENGTH (), LOCATE () или что-то еще, что полагается на счетчик позиций, завершится ошибкой с многобайтовыми символами.
Майкл
68
Вариант SELECT (без создания пользовательской функции):
значения membername без пробела : он добавит всю строку в memberfirst и установит memberlast в NULL.
Значения имени члена, которые имеют несколько пробелов : он добавит все, что находится перед первым пробелом, в memberfirst, а остаток (включая дополнительные пробелы) в memberlast.
Также полезно было бы увидеть, как обрезать только последнее слово для фамилии и все непоследние для имени, например: Мэри А. Смит, это типы, с которыми я должен иметь дело с этим в старой таблице db фикс. Я посмотрю, смогу ли я понять это и опубликовать результат, если нет, если вы тоже можете опубликовать этот вариант, который сделает ваш ответ полным.
Lizardx
как мы можем преобразовать его в целое число, поскольку имя члена - varchar .. пусть memberfirst имеет тип int. Будет ли работать, если я использую cast () напрямую?
infinitywarior
Вы, сэр, заслужили медаль.
rpajaziti
23
Кажется, что существующие ответы слишком сложны или не являются строгим ответом на конкретный вопрос.
Я думаю, что в данной конкретной ситуации нет необходимости иметь дело с именами, состоящими из более чем двух слов. Если вы хотите сделать это правильно, разделение может быть очень сложным или даже невозможным в некоторых случаях:
Иоганн Себастьян Бах
Иоганн Вольфганг фон Гете
Эдгар Аллан По
Якоб Людвиг Феликс Мендельсон-Бартольди
Петефи Шандор
黒 澤 за товар описание
В правильно спроектированной базе данных человеческие имена должны храниться как по частям, так и целиком. Конечно, это не всегда возможно.
Если ваш план должен сделать это как часть запроса, пожалуйста , не делать (а) . Серьезно, это убийца производительности. Могут быть ситуации, когда вас не заботит производительность (например, одноразовые задания по миграции для разделения полей, позволяющие повысить производительность в будущем), но, если вы делаете это регулярно для чего-либо, кроме базы данных микки-мауса, вы зря тратим ресурсы.
Если вы когда-нибудь обнаружите, что каким-то образом обрабатываете только часть столбца, ваша БД имеет изъян. Он вполне может нормально работать с домашней адресной книгой или приложением рецептов или с любой из множества других небольших баз данных, но он не будет масштабироваться до «реальных» систем.
Храните компоненты имени в отдельных столбцах. Почти всегда гораздо быстрее объединить столбцы с помощью простой конкатенации (когда вам нужно полное имя), чем разделить их с помощью поиска по символам.
Если по какой-либо причине вы не можете разделить поле, по крайней мере, добавьте дополнительные столбцы и используйте триггер вставки / обновления для их заполнения. Хотя это и не 3NF, это гарантирует, что данные по-прежнему согласованы, и значительно ускорит ваши запросы. Вы также можете убедиться, что дополнительные столбцы имеют нижний регистр (и индексируются, если вы выполняете поиск по ним) одновременно, чтобы вам не приходилось возиться с проблемами с регистром.
И, если вы даже не можете добавить столбцы и триггеры, имейте в виду (и сообщите своему клиенту, если это для клиента), что он не масштабируется.
(a) Конечно, если вы намерены использовать этот запрос для исправления схемы, чтобы имена помещались в отдельные столбцы в таблице, а не в запросе, я бы счел это допустимым использованием. Но я повторяю, делать это в запросе - не самая лучшая идея.
Иногда вам нужно это делать. Fe Мне это нужно в скрипте миграции, поэтому меня не волнует производительность.
Матье Наполи
@dfmiller, да, ответил, поэтому мой аргументированный и подробный ответ и спасибо за проявленный интерес. Если у вас есть конкретная проблема с тем, что я написал, укажите на это, и я посмотрю, можно ли это исправить. Ваш текущий комментарий практически бесполезен для улучшения ситуации, если это действительно было вашим намерением. Или, может быть, вам просто нравится разбрасывать случайные комментарии в сети, это сложно сказать :-) Я поддерживаю ответ, конечно, доступ к подколонкам не масштабируется и почти всегда является плохой идеей, если только он не используется для целей фактически исправление доступа к подколонкам.
paxdiablo
3
Вопрос в том, как разделить один столбец на 2, а затем вы ответите «Не делайте этого», а затем продолжите объяснять, почему их следует разделить. Ваш первый абзац звучит так, как будто вы аргументируете или сохраняете их как одну колонку, но другие абзацы говорят об обратном.
dfmiller
@dfmiller, возможно, я неправильно понял вопрос, сейчас я не уверен, должно ли быть разделение в запросе или в таблице. Я уточнил ответ, чтобы, надеюсь, было понятнее.
paxdiablo
Намного лучше. Я никогда не рассматривал использование запроса выбора, кроме как для обновления базы данных. Это было бы ужасной идеей.
dfmiller
7
использовать это
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(`membername`,' ',2),' ',1)AS b,
SUBSTRING_INDEX(SUBSTRING_INDEX(`membername`,' ',-1),' ',2)AS c FROM`users`WHERE`userid`='1'
Это приведет к получению первой и последней подстроки, разделенных пробелами, из поля, что не работает во всех случаях. Например, если в поле имени указано «Lilly von Schtupp», то вы получите «Lilly», «Schtupp» в качестве имени, фамилии.
Джон Франклин
5
Не совсем отвечая на вопрос, но столкнувшись с той же проблемой, я сделал это:
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)>3UPDATE 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
Единственный случай, когда вам может понадобиться такая функция, - это запрос UPDATE, который изменит вашу таблицу, чтобы сохранить имя и фамилию в отдельных полях.
Дизайн базы данных должен соответствовать определенным правилам, и нормализация базы данных является одним из наиболее важных.
Излишний комментарий, поскольку это именно то, о чем просил плакат; также неточно, так как в миллион раз вам может потребоваться разделить строку для лучшей нормализации. Не знаю, почему и как за это проголосовали.
daticon
Использование индексов в разделенных полях так же невозможно, как превратить MySQL в мульчер листьев, но это не помешает людям спросить об этом. Хороший ответ - база данных ДОЛЖНА отражать данные, а не характеристики мульчера для листьев.
HoldOffHunger
2
У меня был столбец, в котором имя и фамилия были в одном столбце. Имя и фамилия разделялись запятой. Код ниже работал. НЕТ проверки / исправления ошибок. Просто тупой раскол. Использовал phpMyAdmin для выполнения инструкции SQL.
UPDATE tblAuthorList SET AuthorFirst = SUBSTRING_INDEX(AuthorLast,',',-1), AuthorLast = SUBSTRING_INDEX(AuthorLast,',',1);
Это берет smhg отсюда и curt из последнего индекса данной подстроки в MySQL и объединяет их. Это для mysql, все, что мне нужно, это получить приличное разделение имени на first_name last_name с фамилией одним словом, первым именем перед этим единственным словом, где имя может быть нулевым, 1 словом, 2 словами или более 2 слов. Т.е.: Null; Мэри; Мэри Смит; Мэри А. Смит; Мэри Сью Эллен Смит;
Итак, если name состоит из одного слова или null, last_name имеет значение null. Если name> 1 слова, last_name - это последнее слово, а first_name - все слова перед последним словом.
Обратите внимание, что я уже обрезал такие вещи, как Джо Смит младший; Джо Смит эсквайр. и так далее, вручную, что, конечно, было болезненно, но для этого было достаточно мало, поэтому вы хотите убедиться, что действительно посмотрите на данные в поле имени, прежде чем решить, какой метод использовать.
Обратите внимание, что это также обрезает результат, поэтому вы не останетесь без пробелов перед или после имен.
Я просто отправляю это для других, которые могут найти в Google то, что мне нужно. Это, конечно, работает, сначала проверьте его с помощью select.
Это одноразовая вещь, поэтому меня не волнует эффективность.
Метод, который я использовал для разделения first_name на first_name и last_name, когда все данные поступали в поле first_name. Это поместит только последнее слово в поле фамилии, поэтому «john phillips sousa» будет именем «john phillips» и фамилией «sousa». Это также позволяет избежать перезаписи любых уже исправленных записей.
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)>0and length(trim(last_name))=0
Ответы:
К сожалению, MySQL не поддерживает функцию разделения строк. Однако вы можете создать для этого пользовательскую функцию , например, описанную в следующей статье:
С этой функцией:
вы могли бы построить свой запрос следующим образом:
Если вы предпочитаете не использовать пользовательскую функцию и не возражаете, чтобы запрос был более подробным, вы также можете сделать следующее:
источник
LENGTH
Безопасно ли ваше использование многобайтовых файлов ? "LENGTH (str): возвращает длину строки str, измеренную в байтах. Многобайтовый символ считается как несколько байтов. Это означает, что для строки, содержащей пять 2-байтовых символов, LENGTH () возвращает 10, тогда как CHAR_LENGTH () возвращает 5.»Вариант SELECT (без создания пользовательской функции):
Этот подход также учитывает:
Версия ОБНОВЛЕНИЯ будет:
источник
Кажется, что существующие ответы слишком сложны или не являются строгим ответом на конкретный вопрос.
Думаю, простой ответ - следующий запрос:
Я думаю, что в данной конкретной ситуации нет необходимости иметь дело с именами, состоящими из более чем двух слов. Если вы хотите сделать это правильно, разделение может быть очень сложным или даже невозможным в некоторых случаях:
В правильно спроектированной базе данных человеческие имена должны храниться как по частям, так и целиком. Конечно, это не всегда возможно.
источник
Если ваш план должен сделать это как часть запроса, пожалуйста , не делать (а) . Серьезно, это убийца производительности. Могут быть ситуации, когда вас не заботит производительность (например, одноразовые задания по миграции для разделения полей, позволяющие повысить производительность в будущем), но, если вы делаете это регулярно для чего-либо, кроме базы данных микки-мауса, вы зря тратим ресурсы.
Если вы когда-нибудь обнаружите, что каким-то образом обрабатываете только часть столбца, ваша БД имеет изъян. Он вполне может нормально работать с домашней адресной книгой или приложением рецептов или с любой из множества других небольших баз данных, но он не будет масштабироваться до «реальных» систем.
Храните компоненты имени в отдельных столбцах. Почти всегда гораздо быстрее объединить столбцы с помощью простой конкатенации (когда вам нужно полное имя), чем разделить их с помощью поиска по символам.
Если по какой-либо причине вы не можете разделить поле, по крайней мере, добавьте дополнительные столбцы и используйте триггер вставки / обновления для их заполнения. Хотя это и не 3NF, это гарантирует, что данные по-прежнему согласованы, и значительно ускорит ваши запросы. Вы также можете убедиться, что дополнительные столбцы имеют нижний регистр (и индексируются, если вы выполняете поиск по ним) одновременно, чтобы вам не приходилось возиться с проблемами с регистром.
И, если вы даже не можете добавить столбцы и триггеры, имейте в виду (и сообщите своему клиенту, если это для клиента), что он не масштабируется.
(a) Конечно, если вы намерены использовать этот запрос для исправления схемы, чтобы имена помещались в отдельные столбцы в таблице, а не в запросе, я бы счел это допустимым использованием. Но я повторяю, делать это в запросе - не самая лучшая идея.
источник
использовать это
источник
Не совсем отвечая на вопрос, но столкнувшись с той же проблемой, я сделал это:
источник
В MySQL работает эта опция:
источник
Единственный случай, когда вам может понадобиться такая функция, - это запрос UPDATE, который изменит вашу таблицу, чтобы сохранить имя и фамилию в отдельных полях.
Дизайн базы данных должен соответствовать определенным правилам, и нормализация базы данных является одним из наиболее важных.
источник
У меня был столбец, в котором имя и фамилия были в одном столбце. Имя и фамилия разделялись запятой. Код ниже работал. НЕТ проверки / исправления ошибок. Просто тупой раскол. Использовал phpMyAdmin для выполнения инструкции SQL.
13.2.10 Синтаксис UPDATE
источник
Это берет smhg отсюда и curt из последнего индекса данной подстроки в MySQL и объединяет их. Это для mysql, все, что мне нужно, это получить приличное разделение имени на first_name last_name с фамилией одним словом, первым именем перед этим единственным словом, где имя может быть нулевым, 1 словом, 2 словами или более 2 слов. Т.е.: Null; Мэри; Мэри Смит; Мэри А. Смит; Мэри Сью Эллен Смит;
Итак, если name состоит из одного слова или null, last_name имеет значение null. Если name> 1 слова, last_name - это последнее слово, а first_name - все слова перед последним словом.
Обратите внимание, что я уже обрезал такие вещи, как Джо Смит младший; Джо Смит эсквайр. и так далее, вручную, что, конечно, было болезненно, но для этого было достаточно мало, поэтому вы хотите убедиться, что действительно посмотрите на данные в поле имени, прежде чем решить, какой метод использовать.
Обратите внимание, что это также обрезает результат, поэтому вы не останетесь без пробелов перед или после имен.
Я просто отправляю это для других, которые могут найти в Google то, что мне нужно. Это, конечно, работает, сначала проверьте его с помощью select.
Это одноразовая вещь, поэтому меня не волнует эффективность.
источник
Метод, который я использовал для разделения first_name на first_name и last_name, когда все данные поступали в поле first_name. Это поместит только последнее слово в поле фамилии, поэтому «john phillips sousa» будет именем «john phillips» и фамилией «sousa». Это также позволяет избежать перезаписи любых уже исправленных записей.
источник
источник
mysql 5.4 предоставляет встроенную функцию разделения:
источник