membername
ユーザーの姓と名の両方を含むテーブルフィールドがあります。2つのフィールドにそれらを分割することが可能ですかmemberfirst
、memberlast
?
すべてのレコードは、「Firstname Lastname」という形式(引用符とその間のスペースなし)です。
membername
ユーザーの姓と名の両方を含むテーブルフィールドがあります。2つのフィールドにそれらを分割することが可能ですかmemberfirst
、memberlast
?
すべてのレコードは、「Firstname Lastname」という形式(引用符とその間のスペースなし)です。
回答:
残念ながら、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の長さをバイトで返します。マルチバイト文字は複数バイトとしてカウントされます。これは、5つの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バージョンは次のようになります。
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`
;
この特定の状況では、2語を超える名前を処理する必要はないと思います。適切に実行したい場合、分割が非常に困難になったり、場合によっては不可能になったりします。
適切に設計されたデータベースでは、人間の名前は部分的にも全体的にも格納する必要があります。もちろん、これは常に可能であるとは限りません。
あなたの計画はの一部としてこれを行うのであれば、クエリ、してくださいしていないことを行います() 。真剣に、それはパフォーマンスキラーです。パフォーマンスを気にしない場合もあります(フィールドを分割して将来のパフォーマンスを向上させるための1回限りの移行ジョブなど)が、ミッキーマウスデータベース以外に対して定期的にこれを行う場合は、リソースを無駄にしています。
あなたがいる場合、これまで自分が何らかの方法で列の一部だけを処理する必要が見つけ、あなたのDB設計は欠陥があります。自宅のアドレス帳やレシピアプリケーション、その他の無数の小さなデータベースで問題なく動作する可能性がありますが、「実際の」システムには拡張できません。
名前のコンポーネントを別々の列に格納します。文字検索で列を分割するよりも、列を単純な連結(完全な名前が必要な場合)で結合する方がほぼ常に高速です。
何らかの理由でフィールドを分割できない場合は、少なくとも追加の列を入力し、挿入/更新トリガーを使用してそれらを設定します。これは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
このような関数が必要になる唯一のケースは、FirstnameとLastnameを別々のフィールドに格納するようにテーブルを変更するUPDATEクエリです。
データベースの設計は特定のルールに従う必要があり、データベースの正規化は最も重要なルールの1つです
姓と名の両方が1つの列にある列がありました。姓名はコンマで区切られています。以下のコードは機能しました。エラーのチェック/修正はありません。ばかげた分割。phpMyAdminを使用してSQLステートメントを実行しました。
UPDATE tblAuthorList SET AuthorFirst = SUBSTRING_INDEX(AuthorLast,',',-1) , AuthorLast = SUBSTRING_INDEX(AuthorLast,',',1);
これは、smhgをここから、curt をMySQLの特定のサブストリングのLastインデックスから取得して、それらを結合します。これはmysqlの場合、必要なのは、名前をfirst_name last_nameに適切に分割して、姓を1つの単語、名前がその単一の単語の前にあるすべての名前にすることです。名前はnull、1単語、2単語、または2語以上。すなわち:ヌル。メアリー; メアリー・スミス; メアリーA.スミス; メアリースーエレンスミス;
したがって、nameが1つの単語またはnullの場合、last_nameはnullです。nameが1単語よりも大きい場合、last_nameは最後の単語、first_nameは最後の単語より前のすべての単語です。
Joe Smith Jr.のようなものはすでに削除していることに注意してください。Joe Smith Esq。もちろん、手作業などは大変でしたが、それを行うには十分に小さいため、使用する方法を決定する前に、名前フィールドのデータを実際に確認する必要があります。
これにより結果もトリミングされるため、名前の前後にスペースが含まれることはありません。
私はここに私が必要なものを探してグーグルするかもしれない他の人のためにこれを投稿しています。もちろん、これは機能します。最初にselectでテストしてください。
一度きりなので効率は気にしません。
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
)
);
データがすべてfirst_nameフィールドに到着したときに、first_nameをfirst_nameとlast_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)>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
);
mysql 5.4はネイティブの分割関数を提供します:
SPLIT_STR(<column>, '<delimiter>', <index>)