Oracle function to compare strings in a not ordered way

淺唱寂寞╮ 提交于 2020-01-31 18:34:53

问题


I need a function to make a comparison between two strings withouth considering the order in oracle. i.e. "asd" and "sad" should be considered as equal. Are there similar functions? Or I need to write my own function?


回答1:


This can be done with a simple java function to sort the characters of a string alphabetically:

CREATE AND COMPILE JAVA SOURCE NAMED SORTSTRING AS
public class SortString {
  public static String sort( final String value )
  {
    final char[] chars = value.toCharArray();
    java.util.Arrays.sort( chars );
    return new String( chars );
  }
};
/

Which you can then create a PL/SQL function to invoke:

CREATE FUNCTION SORTSTRING( in_value IN VARCHAR2 ) RETURN VARCHAR2
AS LANGUAGE JAVA NAME 'SortString.sort( java.lang.String ) return java.lang.String';
/

Then you can do a simple comparison on the sorted strings:

SELECT CASE
       WHEN SORTSTRING( 'ads' ) = SORTSTRING( 'das' )
       THEN 'Equal'
       ELSE 'Not Equal'
       END
FROM   DUAL;



回答2:


Not exactly a rocket science, but works (kind of, at least on simple cases).

What does it do? Alphabetically sorts letters in every string and compares them.

SQL> with test (col1, col2) as
  2    (select 'asd', 'sad' from dual),
  3  inter as
  4    (select
  5       col1, regexp_substr(col1, '[^.]', 1, level) c1,
  6       col2, regexp_substr(col2, '[^.]', 1, level) c2
  7     from test
  8     connect by level <= greatest(length(col1), length(col2))
  9    ),
 10  agg as
 11    (select listagg(c1, '') within group (order by c1) col1_new,
 12            listagg(c2, '') within group (order by c2) col2_new
 13     from inter
 14    )
 15  select case when col1_new = col2_new then 'Equal'
 16              else 'Different'
 17         end result
 18  From agg;

RESULT
---------
Equal

SQL> with test (col1, col2) as
  2    (select 'asd', 'sadx' from dual),
<snip>    

RESULT
---------
Different

SQL>



回答3:


Yet another solution, using the SUBSTR function and CONNECT BY loop.

SQL Fiddle

Query 1:

WITH a
     AS (SELECT ROWNUM rn, a1.*
           FROM (    SELECT SUBSTR ('2asd', LEVEL, 1) s1
                       FROM DUAL
                 CONNECT BY LEVEL <= LENGTH ('2asd')
                   ORDER BY s1) a1),
     b
     AS (SELECT ROWNUM rn, a2.*
           FROM (    SELECT SUBSTR ('asd2', LEVEL, 1) s2
                       FROM DUAL
                 CONNECT BY LEVEL <= LENGTH ('asd2')
                   ORDER BY s2) a2)
SELECT CASE COUNT (NULLIF (s1, s2)) WHEN 0 THEN 'EQUAL' ELSE 'NOT EQUAL' END
          res
  FROM a INNER JOIN b ON a.rn = b.rn

Results:

|   RES |
|-------|
| EQUAL |

EDIT : A PL/SQL Sort function for alphanumeric strings.

CREATE OR replace FUNCTION fn_sort(str VARCHAR2) 
  RETURN VARCHAR2 DETERMINISTIC AS 
 v_s VARCHAR2(4000); 
BEGIN 

  SELECT LISTAGG(substr(str, LEVEL, 1), '') 
           within GROUP ( ORDER BY substr(str, LEVEL, 1) ) 
       INTO   v_s 
  FROM   dual 
  CONNECT BY LEVEL < = length(str); 

  RETURN v_s;
END;
/


select  fn_sort('shSdf3213Js') as s
from dual;

|           S |
|-------------|
| 1233JSdfhss |



回答4:


In case you want to create your own sort function, you can use below code,

CREATE OR REPLACE FUNCTION sort_text (p_text_to_sort VARCHAR2) RETURN VARCHAR2
IS
    v_sorted_text VARCHAR2(1000);
BEGIN
    v_sorted_text := p_text_to_sort;
    FOR i IN 1..LENGTH(p_text_to_sort)
    LOOP
        FOR j IN 1..LENGTH(p_text_to_sort)
        LOOP
            IF SUBSTR(v_sorted_text, j, 1)||'' > SUBSTR(v_sorted_text, j+1, 1)||'' THEN
                 v_sorted_text := SUBSTR(v_sorted_text, 1, j-1)||
                                  SUBSTR(v_sorted_text, j+1, 1)||
                                  SUBSTR(v_sorted_text, j, 1)||
                                  SUBSTR(v_sorted_text, j+2);
            END IF;
        END LOOP;
    END LOOP;
    RETURN v_sorted_text;
END;
/

SELECT SORT_TEXT('zlkdsadfsdfasdf') SORTED_TEXT
  FROM dual;

SORTED_TEXT                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     
---------------
aaddddfffklsssz 


来源:https://stackoverflow.com/questions/49172423/oracle-function-to-compare-strings-in-a-not-ordered-way

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!