Tôi đã có một trường bảng membername
chứa cả tên cuối cùng và tên người dùng. Có thể chia những thành 2 lĩnh vực memberfirst
, memberlast
?
Tất cả các bản ghi có định dạng "Tên họ" (không có dấu ngoặc kép và khoảng trắng ở giữa).
Tôi đã có một trường bảng membername
chứa cả tên cuối cùng và tên người dùng. Có thể chia những thành 2 lĩnh vực memberfirst
, memberlast
?
Tất cả các bản ghi có định dạng "Tên họ" (không có dấu ngoặc kép và khoảng trắng ở giữa).
Câu trả lời:
Thật không may, MySQL không có chức năng chuỗi tách. Tuy nhiên, bạn có thể tạo một hàm do người dùng xác định cho việc này, chẳng hạn như hàm được mô tả trong bài viết sau:
Với chức năng đó:
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 ;
bạn sẽ có thể xây dựng truy vấn của mình như sau:
SELECT SPLIT_STR(membername, ' ', 1) as memberfirst,
SPLIT_STR(membername, ' ', 2) as memberlast
FROM users;
Nếu bạn không muốn sử dụng chức năng do người dùng xác định và bạn không ngại truy vấn dài dòng hơn một chút, bạn cũng có thể thực hiện các thao tác sau:
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(membername, ' ', 1), ' ', -1) as memberfirst,
SUBSTRING_INDEX(SUBSTRING_INDEX(membername, ' ', 2), ' ', -1) as memberlast
FROM users;
LENGTH
multibyte có an toàn không? "LENGTH (str): Trả về độ dài của chuỗi str, được đo bằng byte. Một ký tự đa chuỗi được tính là nhiều byte. Điều này có nghĩa là đối với một chuỗi chứa năm ký tự 2 byte, LENGTH () trả về 10, trong khi CHAR_LENGTH () trả về 5. "
Biến thể CHỌN (không tạo chức năng do người dùng xác định):
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`;
Cách tiếp cận này cũng quan tâm đến:
Phiên bản CẬP NHẬT sẽ là:
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
);
Có vẻ như các câu trả lời hiện có quá phức tạp hoặc không phải là một câu trả lời nghiêm ngặt cho câu hỏi cụ thể.
Tôi nghĩ rằng, câu trả lời đơn giản là truy vấn sau đây:
SELECT
SUBSTRING_INDEX(`membername`, ' ', 1) AS `memberfirst`,
SUBSTRING_INDEX(`membername`, ' ', -1) AS `memberlast`
;
Tôi nghĩ rằng không cần thiết phải xử lý các tên nhiều hơn hai từ trong tình huống cụ thể này. Nếu bạn muốn làm điều đó đúng cách, việc chia tách có thể rất khó khăn hoặc thậm chí là không thể trong một số trường hợp:
Trong một cơ sở dữ liệu được thiết kế đúng, tên người nên được lưu trữ cả phần và toàn bộ. Điều này không phải lúc nào cũng có thể, tất nhiên.
Nếu kế hoạch của bạn là thực hiện điều này như một phần của truy vấn, vui lòng không thực hiện điều đó (a) . Nghiêm túc mà nói, đó là một kẻ giết người hiệu suất. Có thể có những tình huống bạn không quan tâm đến hiệu suất (chẳng hạn như các công việc di chuyển một lần để phân chia các trường cho phép hiệu suất tốt hơn trong tương lai), nhưng, nếu bạn làm điều này thường xuyên cho bất kỳ thứ gì ngoài cơ sở dữ liệu chuột mickey, bạn Đang lãng phí tài nguyên.
Nếu bạn từng thấy mình phải xử lý chỉ là một phần của một cột trong một cách nào đó, thiết kế DB của bạn là thiếu sót. Nó có thể hoạt động tốt trên sổ địa chỉ nhà hoặc ứng dụng công thức hoặc bất kỳ cơ sở dữ liệu nhỏ nào khác nhưng nó sẽ không thể mở rộng cho các hệ thống "thực".
Lưu trữ các thành phần của tên trong các cột riêng biệt. Việc kết hợp các cột cùng với một cách ghép đơn giản (khi bạn cần tên đầy đủ) gần như luôn luôn là nhanh hơn nhiều so với việc tìm kiếm chúng tách biệt với tìm kiếm ký tự.
Nếu, vì một số lý do, bạn không thể tách trường, ít nhất là đặt vào các cột bổ sung và sử dụng trình kích hoạt chèn / cập nhật để điền vào chúng. Mặc dù không phải 3NF, nhưng điều này sẽ đảm bảo rằng dữ liệu vẫn nhất quán và sẽ tăng tốc độ truy vấn của bạn một cách ồ ạt. Bạn cũng có thể đảm bảo rằng các cột bổ sung được đặt thấp hơn (và được lập chỉ mục nếu bạn đang tìm kiếm trên chúng) cùng một lúc để không phải loay hoay với các vấn đề trường hợp.
Và, nếu bạn thậm chí không thể thêm các cột và trình kích hoạt, hãy lưu ý (và làm cho khách hàng của bạn biết, nếu đó là cho khách hàng) rằng nó không thể mở rộng được.
(a) Tất nhiên, nếu ý định của bạn là sử dụng truy vấn này để sửa lược đồ sao cho các tên được đặt vào các cột riêng biệt trong bảng thay vì truy vấn, tôi sẽ coi đó là cách sử dụng hợp lệ. Nhưng tôi nhắc lại, thực hiện nó trong truy vấn không thực sự là một ý tưởng tốt.
dùng cái này
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX( `membername` , ' ', 2 ),' ',1) AS b,
SUBSTRING_INDEX(SUBSTRING_INDEX( `membername` , ' ', -1 ),' ',2) AS c FROM `users` WHERE `userid`='1'
Không trả lời chính xác câu hỏi, nhưng đối mặt với cùng một vấn đề tôi đã kết thúc việc này:
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
Trong MySQL, nó hoạt động tùy chọn này:
SELECT Substring(nameandsurname, 1, Locate(' ', nameandsurname) - 1) AS
firstname,
Substring(nameandsurname, Locate(' ', nameandsurname) + 1) AS lastname
FROM emp
Trường hợp duy nhất mà bạn có thể muốn một chức năng như vậy là một truy vấn CẬP NHẬT sẽ thay đổi bảng của bạn để lưu Firstname và Lastname vào các trường riêng biệt.
Thiết kế cơ sở dữ liệu phải tuân theo các quy tắc nhất định và Chuẩn hóa cơ sở dữ liệu là một trong những quy tắc quan trọng nhất
Tôi đã có một cột trong đó cả tên và họ đều nằm trong một cột. Tên và họ được phân tách bằng dấu phẩy. Các mã dưới đây làm việc. KHÔNG có kiểm tra / sửa lỗi. Chỉ là một sự chia rẽ ngu ngốc. Đã sử dụng phpMyAdmin để thực thi câu lệnh SQL.
UPDATE tblAuthorList SET AuthorFirst = SUBSTRING_INDEX(AuthorLast,',',-1) , AuthorLast = SUBSTRING_INDEX(AuthorLast,',',1);
Điều này cần smhg từ đây và giới thiệu từ chỉ mục cuối cùng của một chuỗi con nhất định trong MySQL và kết hợp chúng. Đây là cho mysql, tất cả những gì tôi cần là phân chia tên thành First_name last_name với tên cuối cùng là một từ duy nhất, tên đầu tiên mọi thứ trước từ đó, trong đó tên có thể là null, 1 từ, 2 từ hoặc hơn 2 từ. Tức là: Không; Đức Maria; Mary Smith; Mary A. Smith; Mary Sue Ellen Smith;
Vì vậy, nếu tên là một từ hoặc null, last_name là null. Nếu tên là> 1 từ, last_name là từ cuối cùng và First_name tất cả các từ trước từ cuối cùng.
Lưu ý rằng tôi đã cắt bớt những thứ như Joe Smith Jr .; Joe Smith Esq. và v.v., bằng tay, điều này thật đau đớn, tất nhiên, nhưng nó đủ nhỏ để làm điều đó, vì vậy bạn muốn đảm bảo thực sự xem dữ liệu trong trường tên trước khi quyết định sử dụng phương pháp nào.
Lưu ý rằng điều này cũng cắt bớt kết quả, vì vậy bạn không kết thúc với khoảng trắng ở phía trước hoặc sau tên.
Tôi chỉ đăng bài này cho những người khác có thể google theo cách của họ ở đây để tìm kiếm những gì tôi cần. Điều này hoạt động, tất nhiên, kiểm tra nó với lựa chọn đầu tiên.
Đó là một lần duy nhất, vì vậy tôi không quan tâm đến hiệu quả.
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
)
);
Phương thức tôi đã sử dụng để phân chia First_name thành First_name và last_name khi dữ liệu đến tất cả trong trường First_name. Điều này sẽ chỉ đặt từ cuối cùng trong trường tên cuối cùng, vì vậy "john phillips sousa" sẽ là "john phillips" tên và "sousa" họ. Nó cũng tránh ghi đè bất kỳ hồ sơ đã được sửa chữa.
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
);