Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Làm cách nào tôi có thể CHỌN các hàng tương tự trong hai bảng khác nhau trong MySQL (Có thể không?)

Để triển khai UDF của Khoảng cách Levenshtein thuật toán bạn có thể muốn kiểm tra " codejanitor.com:Khoảng cách Levenshtein dưới dạng một hàm được lưu trữ trong MySQL ":

CREATE FUNCTION LEVENSHTEIN (s1 VARCHAR(255), s2 VARCHAR(255))
RETURNS INT
DETERMINISTIC
BEGIN
  DECLARE s1_len, s2_len, i, j, c, c_temp, cost INT;
  DECLARE s1_char CHAR;
  DECLARE cv0, cv1 VARBINARY(256);
  SET s1_len = CHAR_LENGTH(s1), s2_len = CHAR_LENGTH(s2), cv1 = 0x00, j = 1, i = 1, c = 0;
  IF s1 = s2 THEN
    RETURN 0;
  ELSEIF s1_len = 0 THEN
    RETURN s2_len;
  ELSEIF s2_len = 0 THEN
    RETURN s1_len;
  ELSE
    WHILE j <= s2_len DO
      SET cv1 = CONCAT(cv1, UNHEX(HEX(j))), j = j + 1;
    END WHILE;
    WHILE i <= s1_len DO
      SET s1_char = SUBSTRING(s1, i, 1), c = i, cv0 = UNHEX(HEX(i)), j = 1;
      WHILE j <= s2_len DO
        SET c = c + 1;
        IF s1_char = SUBSTRING(s2, j, 1) THEN SET cost = 0; ELSE SET cost = 1; END IF;
        SET c_temp = CONV(HEX(SUBSTRING(cv1, j, 1)), 16, 10) + cost;
        IF c > c_temp THEN SET c = c_temp; END IF;
        SET c_temp = CONV(HEX(SUBSTRING(cv1, j+1, 1)), 16, 10) + 1;
        IF c > c_temp THEN SET c = c_temp; END IF;
        SET cv0 = CONCAT(cv0, UNHEX(HEX(c))), j = j + 1;
      END WHILE;
      SET cv1 = cv0, i = i + 1;
    END WHILE;
  END IF;
  RETURN c;
END

Bây giờ, hãy tạo một trường hợp thử nghiệm, sử dụng dữ liệu bạn đã cung cấp trong câu hỏi của mình:

CREATE TABLE table_a (name varchar(20));
CREATE TABLE table_b (name varchar(20));

INSERT INTO table_a VALUES('Olde School');      
INSERT INTO table_a VALUES('New School');
INSERT INTO table_a VALUES('Other, C.S. School');
INSERT INTO table_a VALUES('Main School');
INSERT INTO table_a VALUES('Too Cool for School');

INSERT INTO table_b VALUES('Old School');
INSERT INTO table_b VALUES('New ES');
INSERT INTO table_b VALUES('Other School');
INSERT INTO table_b VALUES('Main School');
INSERT INTO table_b VALUES('Hardknocks School');

Sau đó:

SELECT     *
FROM       table_a a
LEFT JOIN  table_b b ON (a.name = b.name);

Rõ ràng là trả về một trận đấu trong đó tên trường khớp chính xác:

+---------------------+-------------+
| name                | name        |
+---------------------+-------------+
| Olde School         | NULL        |
| New School          | NULL        |
| Other, C.S. School  | NULL        |
| Main School         | Main School |
| Too Cool for School | NULL        |
+---------------------+-------------+
5 rows in set (0.00 sec)

Bây giờ chúng ta có thể thử sử dụng LEVENSHTEIN hàm trả về tên trường có chỉnh sửa khoảng cách từ 2 ký tự trở xuống:

SELECT     *
FROM       table_a a
LEFT JOIN  table_b b ON (LEVENSHTEIN(a.name, b.name) <= 2);

+---------------------+-------------+
| name                | name        |
+---------------------+-------------+
| Olde School         | Old School  |
| New School          | NULL        |
| Other, C.S. School  | NULL        |
| Main School         | Main School |
| Too Cool for School | NULL        |
+---------------------+-------------+
5 rows in set (0.08 sec)

Hiện đang sử dụng <= 3 làm ngưỡng khoảng cách chỉnh sửa:

SELECT     *
FROM       table_a a
LEFT JOIN  table_b b ON (LEVENSHTEIN(a.name, b.name) <= 3);

Chúng tôi nhận được kết quả sau:

+---------------------+--------------+
| name                | name         |
+---------------------+--------------+
| Olde School         | Old School   |
| Olde School         | Other School |
| New School          | Old School   |
| Other, C.S. School  | NULL         |
| Main School         | Main School  |
| Too Cool for School | NULL         |
+---------------------+--------------+
6 rows in set (0.06 sec)

Lưu ý cách lần này Olde School cũng khớp với Other SchoolNew School phù hợp với Old School cũng. Đây có thể là dương tính giả và cho thấy rằng việc xác định ngưỡng là rất quan trọng để tránh các kết quả phù hợp không chính xác.

Một kỹ thuật phổ biến để giải quyết vấn đề này là xem xét độ dài của các chuỗi khi áp dụng một ngưỡng. Trên thực tế, trang web đó Tôi đã trích dẫn cho việc triển khai này cũng cung cấp LEVENSHTEIN_RATIO hàm trả về tỷ lệ (dưới dạng phần trăm) của sự khác biệt chỉnh sửa dựa trên độ dài của các chuỗi.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Làm thế nào để CHỌN hàng ngẫu nhiên từ bảng với một số hàng chính xác?

  2. Sử dụng MySQL để xác định xem hôm nay có phải là sinh nhật của người dùng hay không

  3. cố gắng lấy số tháng

  4. laravel có:Không tìm thấy cột

  5. NHibernate IPreUpdateEventListener, IPreInsertEventListener không lưu vào DB