2008-11-19 40 views
32

Tôi muốn tìm kiếm trong bảng của tôi có một cột tên đầu tiên và một cột họ. Tôi hiện chấp nhận cụm từ tìm kiếm từ một lĩnh vực và so sánh nó với cả hai cột, cùng một lúc vớiSử dụng hàm mysql concat() trong mệnh đề WHERE?

select * from table where first_name like '%$search_term%' or 
    last_name like '%$search_term%'; 

này hoạt động tốt với điều kiện tìm kiếm từ duy nhất nhưng kết quả thiết lập bao gồm tất cả mọi người với cái tên "Larry". Nhưng nếu ai đó nhập tên, thì một dấu cách, sau đó họ, tôi muốn có kết quả tìm kiếm hẹp hơn. Tôi đã thử những điều sau mà không thành công.

select * from table where first_name like '%$search_term%' or last_name 
    like '%$search_term%' or concat_ws(' ',first_name,last_name) 
    like '%$search_term%'; 

Bạn có lời khuyên nào?

EDIT: Tên tôi đang thử nghiệm là "Larry Smith". Db lưu trữ "Larry" trong cột "first_name" và "Smith" trong cột "last_name". Các dữ liệu được sạch sẽ, không có thêm không gian và các thuật ngữ tìm kiếm được cắt trái và phải.

CHỈNH SỬA 2: Tôi đã thử câu trả lời của Robert Gamble sáng nay. Anh ấy rất giống với những gì tôi đã chạy tối qua. Tôi không thể giải thích nó, nhưng sáng nay nó hoạt động. Sự khác biệt duy nhất tôi có thể nghĩ đến là đêm qua tôi đã chạy hàm concat làm phân đoạn thứ ba hoặc "" của truy vấn tìm kiếm của tôi (sau khi xem qua first_name và last_name). Sáng nay tôi chạy nó như là phân khúc cuối cùng sau khi xem xét thông qua ở trên cũng như địa chỉ và tên doanh nghiệp.

Việc chạy một hàm mysql ở cuối truy vấn có hoạt động tốt hơn ở giữa không?

+0

Tôi chỉ cần chạy phiên bản bạn đang gặp rắc rối với và nó hoạt động tốt đối với tôi. –

Trả lời

66

Những gì bạn đã phải làm việc nhưng có thể được giảm xuống còn:

select * from table where concat_ws(' ',first_name,last_name) 
like '%$search_term%'; 

Bạn có thể cung cấp một tên ví dụ và thuật ngữ tìm kiếm nơi này không hoạt động?

+0

Tôi đồng ý, tôi đã chạy nó và nó hoạt động như bạn mong đợi ... –

+0

Cú pháp này hay một cái gì đó tương tự được hỗ trợ bởi tất cả các cơ sở dữ liệu? Nó được đề cập trong tiêu chuẩn SQL? –

+0

Có cách nào để làm điều này, mặc dù khác nhau trong tất cả các cơ sở dữ liệu? –

2
SELECT *,concat_ws(' ',first_name,last_name) AS whole_name FROM users HAVING whole_name LIKE '%$search_term%' 

... có lẽ là những gì bạn muốn.

1

Có một vài điều có thể cản trở - dữ liệu của bạn có sạch không?

Có thể bạn có dấu cách ở cuối trường tên đầu tiên, điều này có nghĩa là bạn có hai dấu cách giữa tên và họ khi bạn kết hợp chúng? Sử dụng trim (first_name)/trim (last_name) sẽ sửa lỗi này - mặc dù bản sửa lỗi thực sự là cập nhật dữ liệu của bạn.

Bạn cũng có thể này để phù hợp với nơi hai từ cả hai xảy ra nhưng không nhất thiết với nhau (giả sử bạn đang ở trong php - đó biến $ search_term gợi ý bạn)

$whereclauses=array(); 
$terms = explode(' ', $search_term); 
foreach ($terms as $term) { 
    $term = mysql_real_escape_string($term); 
    $whereclauses[] = "CONCAT(first_name, ' ', last_name) LIKE '%$term%'"; 
} 
$sql = "select * from table where"; 
$sql .= implode(' and ', $whereclauses); 
9

Lưu ý rằng các truy vấn tìm kiếm tại là trường hợp nhạy cảm.

Khi sử dụng

SELECT * FROM table WHERE `first_name` LIKE '%$search_term%' 

Nó sẽ phù hợp với cả hai "Larry" và "larry". Với concat_ws này, nó sẽ đột nhiên trở thành trường hợp nhạy cảm!

này có thể được cố định bằng cách sử dụng các truy vấn sau đây:

SELECT * FROM table WHERE UPPER(CONCAT_WS(' ', `first_name`, `last_name`) LIKE UPPER('%$search_term%') 

Chỉnh sửa: Lưu ý rằng điều này chỉ hoạt động trên các yếu tố phi nhị phân. Xem thêm mynameispaulie's answer.

+0

Xem thêm [câu trả lời] (http://stackoverflow.com/a/13184217/13531) –

+2

Trong trường hợp bạn đang ghép các trường số nguyên thì độ nhạy của trường hợp cũng có thể là kết quả của một lỗi trong MySQL trước phiên bản 5.5 - xem [ answer] (http://stackoverflow.com/questions/6397156/why-concat-does-not-default-to-default-charset-in-mysql) – TheStoryCoder

1

bạn có thể làm điều đó (làm việc trong mysql) SQL lẽ khác nữa .. chỉ cố gắng này:

select * from table where concat(' ',first_name,last_name) 
    like '%$search_term%'; 
+0

đã thử rượu whisky và nó hoạt động rất tốt. thanks –

4

Để Luc:

Tôi đồng ý với câu trả lời của bạn, mặc dù tôi muốn thêm rằng UPPER chỉ hoạt động trên các phần tử không nhị phân. Nếu bạn đang làm việc với nói một cột TUỔI (hoặc bất kỳ số nào), bạn sẽ cần thực hiện chuyển đổi CAST để làm cho hàm UPPER hoạt động chính xác.

SELECT * FROM table WHERE UPPER(CONCAT_WS(' ', first_name, last_name, CAST(age AS CHAR)) LIKE UPPER('%$search_term%'); 

Hãy tha thứ cho tôi vì không trả lời trực tiếp câu trả lời của Luc nhưng trong cuộc sống của tôi, tôi không thể tìm ra cách để làm điều đó. Nếu quản trị viên có thể di chuyển bài đăng của tôi, hãy làm như vậy.

+0

Chào mừng bạn đến với Stack Overflow! Để lại nhận xét yêu cầu [50 danh tiếng] (http://stackoverflow.com/privileges/comment). Có, nó gây phiền nhiễu cho khách truy cập với một cái gì đó hữu ích để thêm, nhưng nó cũng cắt giảm trên trò chuyện không liên quan. Đăng những gì nên là một bình luận như là một câu trả lời là cau mày trong mọi trường hợp, nhưng vì bạn đã cung cấp thông tin liên quan để giải quyết vấn đề nó có lẽ tốt. –

+0

Năm mươi là một giới hạn khá cao:/Dù sao, tôi upvoted câu trả lời của bạn (+10 đại diện) và liên kết với nó trong bài viết của tôi. Cảm ơn bạn đã thêm :) – Luc

+0

Trong trường hợp bạn đang ghép các trường số nguyên thì độ nhạy của trường hợp cũng có thể là kết quả của một lỗi trong MySQL trước phiên bản 5.5 - xem [answer] này (http://stackoverflow.com/questions/6397156/why -concat-do-not-default-to-default-charset-in-mysql) – TheStoryCoder

-1

Bạn có thể thử này:

select * FROM table where (concat(first_name, ' ', last_name)) = $search_term; 
+1

Bạn sẽ phải thêm dấu ngoặc vuông vào '$ search_term' – Naruto

+0

Điều này cũng yêu cầu người dùng nhập chính xác tên thay vì kết hợp từng phần (ví dụ : 'Pat' trùng khớp 'Pat' và 'Patrick') –

Các vấn đề liên quan