我有一個表字段membername
,它包含用戶的姓氏和名字。是否有可能將這些分成兩個字段memberfirst
,memberlast
?將字段拆分爲一個字段
所有的記錄都有這種格式的「名字姓氏」(沒有引號和中間的空格)。
我有一個表字段membername
,它包含用戶的姓氏和名字。是否有可能將這些分成兩個字段memberfirst
,memberlast
?將字段拆分爲一個字段
所有的記錄都有這種格式的「名字姓氏」(沒有引號和中間的空格)。
不幸的是,MySQL不具備分割字符串功能。然而,你可以創建一個user defined function這一點,如下面的文章中描述的:
與該功能:
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;
,你可能希望這樣的功能的唯一情況是一個UPDATE查詢,它將改變你的表來存儲Firstname和Lastname到不同的字段。
數據庫設計必須遵循一定的規則,Database Normalization是最重要的中
使用本
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(`membername` , ' ', 2),' ',1) AS b,
SUBSTRING_INDEX(SUBSTRING_INDEX(`membername` , ' ', -1),' ',2) AS c FROM `users` WHERE `userid`='1'
你能解釋一下嗎? – commonpike 2012-04-13 10:53:24
這將從字段中獲取第一個和最後一個空格分隔的子字符串,這在任何情況下都不起作用。例如,如果姓名字段是「Lilly von Schtupp」,那麼您將得到'Lilly','Schtupp'作爲姓,姓。 – 2012-07-02 20:32:36
如果你的計劃是做到這一點的查詢的一部分,請不要」 t那麼做(a)。嚴重的是,這是一個性能殺手。在某些情況下,您不關心性能(例如一次性遷移作業將字段拆分,以便將來可以獲得更好的性能),但是,如果您經常爲除米老鼠數據庫以外的任何其他目的執行此操作,則您浪費資源。
如果你有有史以來發現自己不得不以某種方式處理某一列的一部分,你的數據庫設計是有缺陷的。它可能適用於家庭地址簿或配方應用程序或任何其他小型數據庫,但它不會擴展到「真實」系統。
將名稱的組件存儲在單獨的列中。通過一個簡單的連接(當你需要全名時)連接字段幾乎總是快得多,而不是通過字符搜索將它們分開。
如果出於某種原因無法拆分字段,至少應放入額外的列並使用插入/更新觸發器來填充它們。雖然不是3NF,但這將保證數據仍然一致,並將大大加快查詢速度。您還可以確保額外的列在同一時間是較小的(並且如果您正在搜索它們,則編入索引),從而無需擺弄案件問題。
而且,如果您甚至無法添加列和觸發器,請注意(並且讓您的客戶端知道,如果它是針對客戶端的)它不可伸縮。
(一)當然,如果你的目的是使用該查詢修復架構,以便名字被放入單獨的列在表而非查詢,我認爲這是一個有效的用途。但我重申,在查詢中這樣做並不是一個好主意。
有時候,你必須這樣做。 F.E.我需要一個移植腳本,所以我不關心表演。 – 2013-11-05 11:13:10
你甚至讀過這個問題嗎? – dfmiller 2014-09-11 16:17:12
@dfmiller,是的,我做了,因此我的理由和詳細的迴應,並感謝您的興趣。如果你對我寫的東西有特定的問題,請指出,我會看看它是否可以改進。如果這確實是你的意圖,那麼你現在的評論對於改善情況幾乎沒有用處。或者,也許你只是在網上發佈隨機評論,很難說:-)我支持答案,當然,分欄訪問是不可擴展的,幾乎總是一個壞主意,除非它用於實際上是_fixing_分欄訪問。 – paxdiablo 2014-09-12 01:47:26
不完全回答這個問題,而是面臨着同樣的問題,我最後做的:
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
如果你不想使用的功能,此查詢處理的事情比清潔其他答案:
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
);
的MySQL 5.4提供了一個天然的分割功能:
SPLIT_STR(<column>, '<delimiter>', <index>)
您能否提供文檔鏈接? dev.mysql.com的搜索結果變幹了。 12.5節在這個功能的評論中確實有一個社區建議。 – DRaehal 2013-07-02 22:21:09
我有一列,其中第一和最後一個名字是兩人都在一列。名字和姓氏之間用逗號隔開。下面的代碼工作。沒有錯誤檢查/更正。只是一個愚蠢的分裂。使用phpMyAdmin來執行SQL語句。
UPDATE tblAuthorList SET AuthorFirst = SUBSTRING_INDEX(AuthorLast,',',-1) , AuthorLast = SUBSTRING_INDEX(AuthorLast,',',1);
這需要從這裏生硬的smhg從Last index of a given substring in MySQL,並結合他們。這是用於mysql的,我所需要的只是將姓氏的名稱拆分爲first_name last_name,姓氏單個單詞,第一個名稱在單個單詞之前,名稱可以爲null,1個單詞,2個單詞或超過2個字。即:空;瑪麗;瑪麗史密斯;瑪麗A.史密斯;瑪麗蘇埃倫史密斯;
因此,如果名稱是一個單詞或null,則last_name爲空。如果名字大於1個單詞,則last_name是最後一個單詞,first_name是最後一個單詞之前的所有單詞。
請注意,我已經削減了像喬史密斯這樣的東西;喬史密斯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
似乎現有的答案是過於複雜或不是對特定問題的嚴格答案。
我認爲,答案很簡單,下面的查詢:
SELECT
SUBSTRING_INDEX(`membername`, ' ', 1) AS `memberfirst`,
SUBSTRING_INDEX(`membername`, ' ', -1) AS `memberlast`
;
我認爲這是沒有必要應對這種特殊情況下更比雙字名。如果你想要做正確的,拆分可以在某些情況下是非常困難甚至是不可能的:
在設計合理的數據庫,人的名字應該被同時存儲在零部件和整體。當然,這並非總是可行的。
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
);
「所有記錄都有這種格式的」名字姓氏「(不帶引號和中間的空格)。」 ......奇蹟般......請**請**,在做數據庫決策時不要忘記像我這樣的人。我經常收到網站告訴我,我的姓氏包含一個*非法*(原文如此)的字符...... :( – 2016-06-02 18:53:26
@StijndeWitt你是對的,但是看起來這個數據庫似乎不包含你的名字,至少不是在我的國家姓是先寫的,所以我也應該在這個數據表中「歧視」,看到這個 - > – 2018-02-07 15:55:25