2009-09-06 37 views
36

Tôi có 2 bảng, nói bảng A và bảng B và tôi muốn thực hiện một phép nối, nhưng điều kiện khớp phải là một cột từ A 'giống như' một cột từ B có nghĩa là bất cứ điều gì có thể đến trước hoặc sau cột trong B:làm thế nào để sử dụng giống như với một tham gia trong sql?

ví dụ: nếu cột trong A là 'foo'. Sau đó, tham gia sẽ phù hợp nếu cột trong B là: 'fooblah', 'somethingfooblah' hoặc chỉ 'foo'. Tôi biết làm thế nào để sử dụng các ký tự đại diện trong một tuyên bố như tiêu chuẩn, nhưng tôi bối rối khi tham gia một. Điều này có nghĩa không? Cảm ơn.

Trả lời

16

Trong MySQL bạn có thể thử:

SELECT * FROM A INNER JOIN B ON B.MYCOL LIKE CONCAT('%', A.MYCOL, '%');

Tất nhiên điều này sẽ là một truy vấn ồ ạt không hiệu quả bởi vì nó sẽ làm một bảng đầy đủ quét.

Cập nhật: Đây là một bằng chứng


create table A (MYCOL varchar(255)); 
create table B (MYCOL varchar(255)); 
insert into A (MYCOL) values ('foo'), ('bar'), ('baz'); 
insert into B (MYCOL) values ('fooblah'), ('somethingfooblah'), ('foo'); 
insert into B (MYCOL) values ('barblah'), ('somethingbarblah'), ('bar'); 
SELECT * FROM A INNER JOIN B ON B.MYCOL LIKE CONCAT('%', A.MYCOL, '%'); 
+-------+------------------+ 
| MYCOL | MYCOL   | 
+-------+------------------+ 
| foo | fooblah   | 
| foo | somethingfooblah | 
| foo | foo    | 
| bar | barblah   | 
| bar | somethingbarblah | 
| bar | bar    | 
+-------+------------------+ 
6 rows in set (0.38 sec) 
+1

Thanks..how tôi sẽ đạt được chức năng tương tự nhưng làm cho nó hiệu quả hơn? –

+0

Đây là cách bạn sẽ làm điều đó. Nếu bạn cần nó hiệu quả hơn, bạn có thể lập chỉ mục trường MYCOL trên bảng B. –

+0

Nếu bạn đang sử dụng loại bảng MyISAM, bạn có thể thử chỉ mục văn bản đầy đủ và xem có giúp được không. Nói chung, mặc dù, tìm kiếm toàn văn không phải là một sức mạnh của MySQL. Nếu tìm kiếm toàn văn bản là một phần cốt lõi của ứng dụng của bạn, hãy xem xét một cái gì đó như Apache Lucene - http://lucene.apache.org/java/docs/ – Asaph

63

Sử dụng INSTR:

SELECT * 
    FROM TABLE a 
    JOIN TABLE b ON INSTR(b.column, a.column) > 0 

Sử dụng NHƯ:

SELECT * 
    FROM TABLE a 
    JOIN TABLE b ON b.column LIKE '%'+ a.column +'%' 

Sử dụng LIKE, với CONCAT:

SELECT * 
    FROM TABLE a 
    JOIN TABLE b ON b.column LIKE CONCAT('%', a.column ,'%') 

tâm rằng trong tất cả các tùy chọn, có thể bạn sẽ muốn lái xe các giá trị cột chữ hoa TRƯỚC so sánh để đảm bảo bạn đang nhận được các trận đấu mà không cần quan tâm đến trường hợp nhạy cảm:

SELECT * 
    FROM (SELECT UPPER(a.column) 'ua' 
     TABLE a) a 
    JOIN (SELECT UPPER(b.column) 'ub' 
     TABLE b) b ON INSTR(b.ub, a.ua) > 0 

Các hiệu quả nhất sẽ phụ thuộc chủ yếu vào các EXPLAIN plan đầu ra.

JOIN các mệnh đề giống hệt với các mệnh đề viết WHERE. Cú pháp JOIN cũng được gọi là ANSI JOIN vì chúng được chuẩn hóa. Không ANSI JOINs trông giống như:

SELECT * 
    FROM TABLE a, 
     TABLE b 
WHERE INSTR(b.column, a.column) > 0 

Tôi sẽ không bận tâm với một ví dụ KHÔNG ANSI LEFT JOIN. Lợi ích của cú pháp ANSI JOIN là nó tách biệt những gì đang nối các bảng với nhau từ những gì đang thực sự xảy ra trong mệnh đề WHERE.

+0

Tốc độ tốt nhất giữa LIKE và INSTR cho (tên miền chẳng hạn) là gì? – Meloman

5

Nếu đây là một cái gì đó bạn sẽ cần phải làm thường ... sau đó bạn có thể muốn denormalize mối quan hệ giữa các bảng A và B.

Ví dụ, trên chèn vào bảng B, bạn có thể viết không hay nhiều mục nhập vào một bảng juncion ánh xạ B đến A dựa trên ánh xạ một phần. Tương tự, các thay đổi đối với một trong hai bảng có thể cập nhật liên kết này.

Tất cả điều này phụ thuộc vào tần suất bảng A và B được sửa đổi. Nếu họ là khá tĩnh, sau đó tham gia một hit trên INSERT là ít đau đớn sau đó lặp đi lặp lại số truy cập vào SELECT.

+2

Đó là một giải pháp tốt, nhưng nó không chính xác để gọi nó là không chuẩn hóa. –

+2

Đủ công bằng. Gọi nó là một bảng nối tiếp –

1

Sử dụng tiêu chí có điều kiện trong tham gia chắc chắn khác với mệnh đề Where. Cardinality giữa các bảng có thể tạo ra sự khác biệt giữa Joins và mệnh đề Where.

Ví dụ: sử dụng điều kiện Thích trong Tham gia bên ngoài sẽ giữ tất cả các bản ghi trong bảng đầu tiên được liệt kê trong kết nối.Sử dụng cùng một điều kiện trong mệnh đề Where sẽ ngầm thay đổi tham gia thành một phép nối Inner. Bản ghi nói chung phải có mặt trong cả hai bảng để hoàn thành việc so sánh có điều kiện trong mệnh đề Where.

Tôi thường sử dụng kiểu được đưa ra trong một trong các câu trả lời trước.

tbl_A as ta 
    LEFT OUTER JOIN tbl_B AS tb 
      ON ta.[Desc] LIKE '%' + tb.[Desc] + '%' 

Bằng cách này tôi có thể kiểm soát loại tham gia.

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