Как получить почти совпадающую строку из таблицы Oracle?

У меня есть таблица в Oracle с четырьмя столбцами.Данные таблицы в Oracle

Теперь пользователь может ввести входную строку как "операция по колено вправо" (которая действительна) для моего запроса, и мой запрос должен вернуть код ICD (IKR123), который соответствует большей части слова в столбце DiagnosisName.

Ниже приведен мой текущий запрос (не выдает правильный вывод)

SELECT diagnosisname
FROM
  (SELECT diagnosisname,
    UTL_MATCH.jaro_winkler_similarity('%operation Knee right%',diagnosisname)
  FROM icd_code
  ORDER BY UTL_MATCH.EDIT_DISTANCE_SIMILARITY('%operation Knee right%',diagnosisname) DESC
  )
WHERE ROWNUM<2;

Этот запрос дает мне вывод "Операция на левом колене", но я ожидаю "Операция на правом колене".

2 ответа

Решение

Есть несколько замечаний по поводу использования UTL_MATCH:

  • EDIT_DISTANCE_SIMILARITY: возвращает целое число от 0 до 100, где 0 указывает на отсутствие сходства вообще, а 100 указывает на идеальное совпадение.
  • JARO_WINKLER_SIMILARITY: Возвращает целое число от 0 до 100, где 0 указывает на отсутствие сходства вообще, а 100 указывает на идеальное совпадение, но пытается учесть возможные ошибки ввода данных.

ORDER BY UTL_MATCH.EDIT_DISTANCE_SIMILARITY ('% операция по колено справа%', имя диагноза) DESC

Это не даст вам правильного результата. Поскольку вы рассматриваете только возможное сходство, но не учитывает ошибки при вводе данных. Итак, вы должны использовать JARO_WINKLER_SIMILARITY.

операция по колено справа

Вы должны иметь в виду случай ввода и значения столбца для сравнения. Они должны быть в аналогичном случае для правильного соответствия. Вы передаете ввод в LOWERCASE, однако значения вашего столбца находятся в INITCAP. Лучше преобразовать значения столбца и входные данные в аналогичный случай.

Давайте посмотрим на демонстрацию ниже, чтобы понять:

SQL> WITH DATA AS(
  2  SELECT 'Heart Operation' diagnosis_name, 'IH123' icd_code FROM dual UNION ALL
  3  SELECT 'Knee Operation' diagnosis_name, 'IK123' icd_code FROM dual UNION ALL
  4  SELECT 'Left Knee Operation' diagnosis_name, 'IKL123' icd_code FROM dual UNION ALL
  5  SELECT 'Right Knee Operation' diagnosis_name, 'IKR123' icd_code FROM dual UNION ALL
  6  SELECT 'Fever' diagnosis_name, 'IF123' icd_code FROM dual
  7  )
  8  SELECT t.*,
  9    utl_match.edit_distance_similarity(upper(diagnosis_name),upper('operation Knee right')) eds,
 10    UTL_MATCH.jaro_winkler_similarity (upper(diagnosis_name),upper('operation Knee right')) jws
 11  FROM DATA t
 12  ORDER BY jws DESC
 13  /

DIAGNOSIS_NAME       ICD_CO        EDS        JWS
-------------------- ------ ---------- ----------
Right Knee Operation IKR123         20         72
Knee Operation       IK123          20         70
Heart Operation      IH123          25         68
Left Knee Operation  IKL123         25         64
Fever                IF123          15         47

SQL>

Итак, вы видите, как оба отличаются друг от друга. jaro_winkler_simility лучше справляется с выявлением ошибок при вводе данных и дает наиболее точное совпадение. Исходя из этого, просто выберите первую строку после сортировки по убыванию:

SQL> WITH DATA AS(
  2  SELECT 'Heart Operation' diagnosis_name, 'IH123' icd_code FROM dual UNION ALL
  3  SELECT 'Knee Operation' diagnosis_name, 'IK123' icd_code FROM dual UNION ALL
  4  SELECT 'Left Knee Operation' diagnosis_name, 'IKL123' icd_code FROM dual UNION ALL
  5  SELECT 'Right Knee Operation' diagnosis_name, 'IKR123' icd_code FROM dual UNION ALL
  6  SELECT 'Fever' diagnosis_name, 'IF123' icd_code FROM dual
  7  )
  8  SELECT diagnosis_name
  9  FROM
 10    (SELECT t.*,
 11      utl_match.edit_distance_similarity(upper(diagnosis_name),upper('operation Knee right')) eds,
 12      UTL_MATCH.jaro_winkler_similarity (upper(diagnosis_name),upper('operation Knee right')) jws
 13    FROM DATA t
 14    ORDER BY jws DESC
 15    )
 16  WHERE rownum = 1
 17  /

DIAGNOSIS_NAME
--------------------
Right Knee Operation

SQL>

Пожалуйста, попробуйте этот запрос. Это может помочь решить вашу проблему.

SELECT diagnosisname 
   FROM (SELECT diagnosisname, UTL_MATCH.jaro_winkler_similarity('%operation Knee right%',diagnosisname) 
   FROM icd_code 
   WHERE UTL_MATCH.jaro_winkler_similarity('%operation Knee right%',diagnosisname) = 100
   ORDER BY UTL_MATCH.EDIT_DISTANCE_SIMILARITY('%operation Knee right%',diagnosisname) DESC) 
WHERE ROWNUM<2
Другие вопросы по тегам