2012-02-22 73 views
5

Tôi muốn biết nếu có cách nào, trong Oracle SQL, để so sánh hai chuỗi cho các điểm tương đồng khác với = hoặc like. Ví dụ, SQL Server có một hàm difference(str1, str2) so sánh hai chuỗi và đưa ra một đánh giá tương tự (0 đến 4). Không chính xác những gì tôi muốn nhưng điều đó vẫn sẽ cực kỳ hữu ích.So sánh chuỗi nâng cao trong Oracle SQL

Tôi đã hy vọng đặc biệt cho chức năng hoặc các phương pháp rằng sẽ:

  1. Hãy so sánh một chuỗi ký tự bằng ký tự (trả về số các trận đấu chính xác)
  2. Nói bao nhiêu ký tự nằm trong một chuỗi, nhưng tại địa điểm sai

Việc sử dụng chính sẽ là cho các chuỗi có cùng độ dài, chứa số (ID, số điện thoại, v.v.) cho mục đích của tôi, tôi sẽ sử dụng nó để tìm các kết quả phù hợp có thể etters/số có thể đã được transposed. Soundex(string) hoạt động tốt cho chuỗi alpha nhưng dường như bỏ qua các số (vì lý do chính đáng).

Tôi không có quyền tự tạo các chức năng, nhưng nếu ai đó biết phương pháp làm điều đó, tôi muốn nghe nó. Một giải pháp để so sánh char-to-char (mà chỉ hoạt động nếu bạn biết số MAX ký tự) là:

--For char-to-char counts 
    Decode(substr(ID1,1,1), substr(ID2,1,1), 1, 0) + 
    Decode(substr(ID1,2,1), substr(ID2,2,1), 1, 0) + 
    [...] 
    Decode(substr(ID1,N,1), substr(ID2,N,1), 1, 0) 

Nhưng đó là khoảng không thanh nha như bạn có thể nhận được.

Mọi trợ giúp sẽ được đánh giá cao.

+0

bản sao có thể có của [Tìm kết quả phù hợp nhất cho giá trị chuỗi - Oracle/Java] (http://stackoverflow.com/questions/8068162/finding-best-matches-for-a-string-value-oracle-java) –

Trả lời

20

Có vẻ như bạn đang tìm kiếm UTL_MATCH package

SELECT utl_match.edit_distance(string1, string2) 
    FROM dual 

cho bạn biết số chỉnh sửa cần thiết để chuyển đổi chuỗi1 vào chuỗi2

SQL> select utl_match.edit_distance('Bear', 'berry') from dual; 

UTL_MATCH.EDIT_DISTANCE('BEAR','BERRY') 
--------------------------------------- 
             3 

Ngoài ra còn có một vài chức năng tương tự EDIT_DISTANCE_SIMILARITYJARO_WINKLER_SIMILARITY cung cấp điểm số tương tự giữa 0 và 100 cho bạn ý tưởng về các chuỗi tương tự như thế nào.

+0

Điều này thật tuyệt vời. Tôi rất vui mừng về khả năng với những bộ chức năng này! Điều này là tốt hơn nhiều so với tôi đã hy vọng, cảm ơn bạn rất nhiều cho bài viết của bạn. – Phillip

+0

Không chắc chắn nếu điều này giống hoặc khác với hàm Ld(). Tôi tin Ld là viết tắt của Levenschtein. – jinglesthula

+0

@jinglesthula - Hàm 'edit_distance' sử dụng thuật toán khoảng cách Levenshtein. Tôi không chắc chắn về chức năng 'Ld' của ngôn ngữ mà bạn đang đề cập đến-- đó không phải là một chức năng mà là một phần của cơ sở dữ liệu cơ sở cài đặt-- vì vậy tôi không chắc liệu đó có phải là điều tương tự hay không. Có lẽ ai đó trong tổ chức của bạn đã tạo ra một hàm 'LD' gọi là' utl_match.edit_distance'? Hoặc có lẽ họ đã triển khai lại thuật toán. –

1

Có một số cách để giải quyết này trong Oracle:

  1. Bạn có thể tạo một thủ tục lưu trữ.

  2. Bạn có thể tải mã Java lên một DB Oracle và sử dụng các hàm được xác định trong mã (intro).

  3. Bạn có thể tìm nạp chuỗi từ cơ sở dữ liệu và so sánh chúng trong ứng dụng của bạn.

Ưu/nhược điểm:

thủ tục cửa hàng là hơi khó để viết và duy trì và họ có thể được làm chậm. Nhưng chúng là công cụ tiêu chuẩn, thường được sử dụng, vì vậy trừ khi công ty của bạn có chính sách "không đi" nghiêm ngặt, chúng thường là "giải pháp" (thường giống như cụm từ thông dụng, giải quyết một vấn đề và tạo hai vấn đề mới).

Mã Java là một công cụ cực kỳ mạnh mẽ nhưng tôi đã thấy nhiều cài đặt Oracle và cho đến nay không ai sử dụng mã Java. Tôi không chắc lý do là gì, nhiều người dường như cảnh giác nhưng không có gì vững chắc từng được thực hiện. Cũng lưu ý rằng các máy chủ DB được tối ưu hóa cho IO và ít hơn cho CPU. Vì vậy, mã Java phức tạp có thể làm hỏng hiệu suất của bạn theo nhiều cách hơn bạn có thể mong đợi (theo các dòng "nhiều cảnh giác")

Giải pháp cuối cùng luôn hoạt động nhưng tùy thuộc vào nhu cầu của bạn. Mặt khác, tôi đã thấy mã thực hiện nhiều hơn tốt hơn bằng cách tải xuống rất nhiều dữ liệu và thực hiện xử lý phức tạp trong ứng dụng. Trong một ví dụ, truy vấn sẽ mất 15 giây và tải xuống + dòng lệnh grep(1) mất 0,3 giây.