문자열 거꾸로 조회 후 오름차순 정렬하는 방법이 있을까요?? ㅠ 0 15 2,225

by 도와주십시요 ㅠ,ㅜ [2017.01.23 11:08:22]


문자열 거꾸로 조회 후 오름차순 정렬하는 방법이 있을까요?? ㅠ

예를 들어

한국어 (왼쪽에서 오른쪽으로 입력 "훈민정음만세") , 왼쪽 기준

아랍어 (오른쪽에서 왼쪽으로 입력 "세음정민훈"), 오른쪽 기준

 

A라는 컬럼에 데이터가 아래와 같이

세만음정민훈

다좋음정민훈

고최음정민훈

음정민훈은좋

음정민훈정인

 

데이터가 5개 있다고 생각하고 음정민훈 또는  훈민정음이나 으로 조회시 아래와 같이 오름차순으로 나오게 하는 방법이 있을가요?

(데이터가 오른쪽 기준으로 오름차순이니 ㄱ~ㅎ  , 좋 인 훈 , 순으로 출력)

음정민훈은

음정민훈정

세만음정민

다좋음정민

고최음정민

 

조언좀 부탁드립니다.

 

 

by 우리집아찌 [2017.01.23 13:20:42]
-- 원하시는게 맞는지 모르겠네요.
WITH T ( TXT ) AS (
SELECT '세만음정민훈' FROM DUAL UNION ALL
SELECT '다좋음정민훈' FROM DUAL UNION ALL
SELECT '고최음정민훈' FROM DUAL UNION ALL
SELECT '음정민훈은좋' FROM DUAL UNION ALL
SELECT '음정민훈정인' FROM DUAL
)

SELECT T.* 
  FROM T 
 WHERE REGEXP_LIKE(T.TXT,'[음정민훈|훈민정음]') 
 ORDER BY SUBSTR(T.TXT,LENGTH(T.TXT) ,1) ASC

 


by 마농 [2017.01.23 13:37:15]

1. Reverse 라고 하는 비공식 함수가 있긴 한데...
  - 한글은 안먹히네요. 비공식인 이유가 있는듯.
  - 영문인 경우엔 사용 가능
2. 글자수만큼 복제하여 문자를 쪼개어 역순으로 다시 붙이는 방식도 가능한데...
  - 성능이 떨어질 듯.

WITH t AS
(
SELECT 1 idx, '세만음정민훈' a FROM dual
UNION ALL SELECT 2, '다좋음정민훈' FROM dual
UNION ALL SELECT 3, '고최음정민훈' FROM dual
UNION ALL SELECT 4, '음정민훈은좋' FROM dual
UNION ALL SELECT 5, '음정민훈정인' FROM dual
)
SELECT idx, a
     , LISTAGG(SUBSTR(a, lv, 1)) WITHIN GROUP(ORDER BY lv DESC) b
  FROM t
     , (SELECT LEVEL lv FROM dual CONNECT BY LEVEL <= 99)
 WHERE lv <= LENGTH(a)
 GROUP BY idx, a
 ORDER BY b
;


3. 글자수가 길지 않은 단어 수준이라면?
  - 복제 없이 그냥 쪼개어 정렬해도 될 듯
  - 단, 성능은 향상되나 무식해 보일 수 있음.

SELECT idx, a
  FROM t
 ORDER BY SUBSTR(a, -1, 1)
        , SUBSTR(a, -2, 1)
        , SUBSTR(a, -3, 1)
        , SUBSTR(a, -4, 1)
        , SUBSTR(a, -5, 1)
        , SUBSTR(a, -6, 1)
        , SUBSTR(a, -7, 1)
        , SUBSTR(a, -8, 1)
        , SUBSTR(a, -9, 1)
;

 


by 신이만든짝퉁 [2017.01.23 13:41:59]
-- 아랍 어휘순으로 정렬
SELECT *
  FROM TABLE
 ORDER BY NLSSORT(COL1, 'NLS_SORT=ARABIC');
 
 -- 아랍어 관련
ARABIC_ABJ_MATCH
ARABIC_ABJ_SORT
ARABIC_MATCH

아랍어 예제가 없어서 테스트는 못해봤으나, 이렇게 한번 시도해 보세요.


by 도와주십시요 ㅠ,ㅜ [2017.01.23 13:47:54]

우리집아찌님~

마농님

신이만든짝퉁님 조언 주셔서 감사합니다. ~~!!

열공 하겠습니다.

구글 검색 해보니 REVERS INDEX 라는것도 있던데 지금 테스트환경이 안되서

요것도 같이 공부해봐야겠네요

새해복 많이 받으세용!!

 

by 신이만든짝퉁 [2017.01.23 13:56:41]

REVERSE INDEX는 인덱스 블럭의 경합을 막기 위해서 고안된 인덱스 구조입니다.

그러므로 요구하신 데이터 정렬과는 맞지 않습니다.
 


by 마농 [2017.01.23 14:04:53]

Reverse Index 는
  - 데이터가 시간의 흐름에 따라 한쪽으로 몰리게 되는데
  - 이러한 치우침 현상을 방지하고자 하는 목적이 크구요
  - 이퀄 검색만 허용하며 범위검색은 안됩니다.
  - 전체 검색으로 Index Full Sacn 한다면 가능하기는 하겠으나?
  - Reverse 함수를 주고 정렬했을 때와 동일한 결과가 나오는 걸로 봐서는
  - reverse Index 내부적으로 Reverse 함수를 이용하는 듯 하네요?
  - 한글 깨짐 현상이 있어서 제대로 정렬이 안되네요.


by 신이만든짝퉁 [2017.01.23 14:12:52]

확인해 보니 별다른 작업을 하지 않아도

아랍어가 들어간 컬럼을 order by 하기만 해도 자동으로 정렬되네요.
 


by 도와주십시요 ㅠ,ㅜ [2017.01.23 14:21:25]
아랍어가 들어간 컬럼을 order by 하기만 해도 자동으로 정렬되네요.라는 말씀은
답변 주신 아래 쿼리로 하면 결과값이 재가 원하는게 나온다는 말슴이신지요??
 
-- 아랍 어휘순으로 정렬
SELECT *
  FROM TABLE
 ORDER BY NLSSORT(COL1, 'NLS_SORT=ARABIC');
  
 -- 아랍어 관련
ARABIC_ABJ_MATCH
ARABIC_ABJ_SORT
ARABIC_MATCH
 

by 신이만든짝퉁 [2017.01.23 14:27:07]

select * from table order by col asc;

이렇게 해도 자동으로 정렬된다는 의미입니다.(col 이 아랍어가 들어간 컬럼)


by 신이만든짝퉁 [2017.01.23 14:27:59]

테스트는 여기서 해봤습니다.

 

https://livesql.oracle.com


by 신이만든짝퉁 [2017.01.23 14:33:21]
with t as (
select 'ذراع' text from dual union all
select 'ظهر' from dual union all
select 'خدين' from dual union all
select 'صدر' from dual)
select * from t
order by text asc;

with t as (
select 'ذراع' text from dual union all
select 'ظهر' from dual union all
select 'خدين' from dual union all
select 'صدر' from dual)
select * from t
order by nlssort(text, 'NLS_SORT=ARABIC')
with t as (
select 'ـا' text from dual union all
select 'ـب' from dual union all
select 'ـج' from dual union all
select 'ـت' from dual)
select * from t
order by text;

테스트 데이터는 위와 같이 해봤습니다.


by 마농 [2017.01.23 14:47:04]

궁금해요~
테스트 결과표도 보여주세요.
결과가 어떤 의미를 갖는지 설명좀 해주세요?
아랍어를 모르니 결과가 어떻게 나와야 맞는건지도 모르겠음...
 


by 신이만든짝퉁 [2017.01.23 15:19:20]

저도 아랍어는 잘 모르지만, 아랍 알파벳을 구글에서 검색해보니 아래와 같은 순서라는 것을 알 수 있습니다.

아랍어 알파벳 : http://mylanguages.org/ko/arabic_alphabet.php

참고사항 :  위 알파벳이 순서대로 정렬된 것이 아니라면, 아래 가정은 틀릴 수 있습니다. ^^;


with t as (
select 'ـا' text from dual union all
select 'ـب' from dual union all
select 'ـج' from dual union all
select 'ـت' from dual)
select * from t;

TEXT
ـا
ـب
ـج
ـت


4 rows selected.


with t as (
select 'ـا' text from dual union all
select 'ـب' from dual union all
select 'ـج' from dual union all
select 'ـت' from dual)
select * from t
order by text asc;

TEXT
ـا
ـب
ـت
ـج


4 rows selected.

-- 위 아랍어 알파벳 사이트에서 알파벳 순서를 확인해보면 1,2,4,3 순으로 표기됩니다.

with t as (
select 'ـا1' text from dual union all
select 'ـب2' from dual union all
select 'ـج3' from dual union all
select 'ـت4' from dual)
select * from t;

TEXT
ـا1
ـب2
ـج3
ـت4


4 rows selected.

-- 해당 컬럼을 정렬하면 알파벳 순으로 정렬됨
with t as (
select 'ـا1' text from dual union all
select 'ـب2' from dual union all
select 'ـج3' from dual union all
select 'ـت4' from dual)
select * from t
order by text asc;

TEXT
ـا1
ـب2
ـت4
ـج3


4 rows selected.

-- 강제로 정렬방식을 아랍어순으로 변경한 경우로, 결과가 위와 동일함
with t as (
select 'ـا1' text from dual union all
select 'ـب2' from dual union all
select 'ـج3' from dual union all
select 'ـت4' from dual)
select * from t
order by nlssort(text, 'NLS_SORT=ARABIC');


TEXT
ـا1
ـب2
ـت4
ـج3


4 rows selected.

그러므로 따로 처리를 하지 않아도 오라클은 아랍어를 오른쪽에서 왼쪽 어순으로 자동으로 정렬해 준다는 것을 확인할 수 있었습니다.


by 마농 [2017.01.23 15:40:46]

와 신기하네요. 헐~ 대박~
아랍어 치면 자동으로 우에서 좌로 채워지네요..
눈에 보이는대로 좌측거 지운다고 맨 앞에 커서 놓고 딜리트 누르면 우측게 지워짐.
눈에 보이는대로 우측거 지운다고 맨 뒤에 커서 놓고 백스페이스 누르면 좌측게 지워짐.
DUMP 를 떠보면 실제로는 타이핑 치는 그대로 좌에서 우로 저장되네요.
대신 화면에 보일 때만 거꾸로 보이는 듯?
 

WITH t AS
(
SELECT 'ـ' text FROM dual  -- b
UNION ALL SELECT 'ا' text FROM dual  -- a
UNION ALL SELECT 'ـا' text FROM dual  -- ab 로 보임(실제로는 타이핑 순서대로 ba 로 저장됨)
)
SELECT text
     , DUMP(text, 16)
  FROM t
 ORDER BY text
;
-- 결과 --
ا   Typ=1 Len=2: d8,a7
ـ   Typ=1 Len=2: d9,80
ـا Typ=1 Len=4: d9,80,d8,a7

 


by 도와주십시요 ㅠ,ㅜ [2017.01.23 16:05:27]

와... 진짜 신기하네 아랍어가 뒤로 저절로 밀리네???? 헐......

그럼 결론적으로 아랍어를 입력하게 되면 자동으로

1. 문자열 오른쪽부터 기준 이됨

2. 오른쪽 문자열 아랍어순 (예: a, b,c,d 라고 예를들면) 으로 정렬 됨

3. 재가 질문올린것은 오라클에서 아랍어로 자동처리 됨으로 신경쓸필요 없음.

4. 오라클 짱짱 맨!!

5. 마농님 짝퉁님 오랜시간 조언 주셔서 정말 감사합니다. ㅠ,ㅠ

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입