Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Cортировка внутри varchar2  [new]
Maart
Member

Откуда:
Сообщений: 112
Возникла задача строку varchar2 (формат: <длина слова>||'$'||<слово>):

4$сссс3$aaa2$bb

переделать в другую строку, остортировав слова в ней в алфавитном порядке:

3$aaa2$bb4$сссс

Как это сделать лучше всего?
16 ноя 10, 13:31    [9787182]     Ответить | Цитировать Сообщить модератору
 Re: Cортировка внутри varchar2  [new]
Mikst
Member

Откуда: Москва
Сообщений: 983
Maart,

Разбить строку на слова , отсортировать и прифигачить <длину слова>||'$' впереди, после чего слепить обратно.

ключевые слова
CONNECT BY
SUBSTR
INSTR
LENGTH
TRANSLATE
16 ноя 10, 13:35    [9787216]     Ответить | Цитировать Сообщить модератору
 Re: Cортировка внутри varchar2  [new]
suPPLer
Member

Откуда: Харків, Україна
Сообщений: 7794
Блог
Maart,

написать функцию.
16 ноя 10, 13:36    [9787220]     Ответить | Цитировать Сообщить модератору
 Re: Cортировка внутри varchar2  [new]
Elic
Member

Откуда:
Сообщений: 29987
Mikst
Разбить строку на слова
CONNECT BY
Продемонстрируешь, хотя бы словами, как будешь использовать длину слова?
16 ноя 10, 13:44    [9787308]     Ответить | Цитировать Сообщить модератору
 Re: Cортировка внутри varchar2  [new]
orawish
Member

Откуда: Гадюкино-2 (City)
Сообщений: 15487
suPPLer
Maart,

написать функцию.

или модел
16 ноя 10, 13:48    [9787345]     Ответить | Цитировать Сообщить модератору
 Re: Cортировка внутри varchar2  [new]
orawish
Member

Откуда: Гадюкино-2 (City)
Сообщений: 15487
Elic
Mikst
Разбить строку на слова
CONNECT BY
Продемонстрируешь, хотя бы словами, как будешь использовать длину слова?

да вроде можно. не использовать, а можно спокойно на неё забить.
сама строка на цифирки заканчиваться не может (иначе основной, неведомый нам, распаковщик офанареет)
16 ноя 10, 13:54    [9787411]     Ответить | Цитировать Сообщить модератору
 Re: Cортировка внутри varchar2  [new]
Elic
Member

Откуда:
Сообщений: 29987
orawish
...
или модел
или recursive subquery factoring (11gR2)
16 ноя 10, 13:56    [9787426]     Ответить | Цитировать Сообщить модератору
 Re: Cортировка внутри varchar2  [new]
orawish
Member

Откуда: Гадюкино-2 (City)
Сообщений: 15487
orawish
Elic
пропущено...
Продемонстрируешь, хотя бы словами, как будешь использовать длину слова?

да вроде можно. не использовать, а можно спокойно на неё забить.
сама строка на цифирки заканчиваться не может (иначе основной, неведомый нам, распаковщик офанареет)

упс. был не прав.
16 ноя 10, 13:56    [9787435]     Ответить | Цитировать Сообщить модератору
 Re: Cортировка внутри varchar2  [new]
suPPLer
Member

Откуда: Харків, Україна
Сообщений: 7794
Блог
[quot orawishсама строка на цифирки заканчиваться не может (иначе основной, неведомый нам, распаковщик офанареет)[/quot]

Почему? Есть длина слова, есть разделитель длины от слова, есть слово той длины, что идёт вначале. Хоть всё слово из цифр сделать - главное, чтобы заявленная длина совпадала с действительной.
16 ноя 10, 13:57    [9787447]     Ответить | Цитировать Сообщить модератору
 Re: Cортировка внутри varchar2  [new]
Elic
Member

Откуда:
Сообщений: 29987
orawish
Elic
как будешь использовать длину слова?
да вроде можно. не использовать, а можно спокойно на неё забить.
сама строка на цифирки заканчиваться не может
Не обязана: 4$сссс7$aaa2$bb
orawish
(иначе основной, неведомый нам, распаковщик офанареет)
Практически полной аналогии с физической структурой строки в блоке не видишь? :)
16 ноя 10, 14:00    [9787469]     Ответить | Цитировать Сообщить модератору
 Re: Cортировка внутри varchar2  [new]
bdsm_sql
Member

Откуда:
Сообщений: 948
WITH t AS (SELECT '4$сссс3$aaa2$bb' s FROM dual)
SELECT LISTAGG(LENGTH(lx) || '$' || lx) WITHIN GROUP (ORDER BY lx) FROM (
SELECT SUBSTR(s, st, en - st) lx FROM (
SELECT s, st, COALESCE(LEAD(st) OVER (ORDER BY ROWNUM) - 2, LENGTH(s) + 1) en FROM (
SELECT s, REGEXP_INSTR(s, '\d+\$', 1, LEVEL) + 2 st FROM t
CONNECT BY REGEXP_INSTR(s, '\d+\$', 1, LEVEL) <> 0
)))
16 ноя 10, 14:06    [9787519]     Ответить | Цитировать Сообщить модератору
 Re: Cортировка внутри varchar2  [new]
bdsm_sql
Member

Откуда:
Сообщений: 948
десятка
WITH t AS (SELECT '4$сссс3$aaa2$bb' s FROM dual)
SELECT REPLACE(REPLACE(x, '<XXX>'), '</XXX>') FROM (
SELECT XMLAGG(XMLELEMENT("XXX", LENGTH(lx) || '$' || lx) ORDER BY lx) x FROM (
SELECT SUBSTR(s, st, en - st) lx FROM (
SELECT s, st, COALESCE(LEAD(st) OVER (ORDER BY ROWNUM) - 2, LENGTH(s) + 1) en FROM (
SELECT s, REGEXP_INSTR(s, '\d+\$', 1, LEVEL) + 2 st FROM t
CONNECT BY REGEXP_INSTR(s, '\d+\$', 1, LEVEL) <> 0
))))
16 ноя 10, 14:07    [9787526]     Ответить | Цитировать Сообщить модератору
 Re: Cортировка внутри varchar2  [new]
orawish
Member

Откуда: Гадюкино-2 (City)
Сообщений: 15487
suPPler, Elic,

всё правильно говорите (я уже отполз - на кнопке :)
16 ноя 10, 14:13    [9787569]     Ответить | Цитировать Сообщить модератору
 Re: Cортировка внутри varchar2  [new]
bdsm_sql
Member

Откуда:
Сообщений: 948
с другой стороны, я написал лажу, оно не работает
с 4$44445$aaaaa
16 ноя 10, 14:14    [9787573]     Ответить | Цитировать Сообщить модератору
 Re: Cортировка внутри varchar2  [new]
Eras
Member

Откуда: Вильнюс
Сообщений: 123
во накурил :)

with t1 as(select '4$сссс3$aaa2$bb' txt from dual)
select txt,
       ordered_txt
from (select txt,
             regexp_replace(sys_connect_by_path(txt_1, '|'), '\|', '') ordered_txt
      from (select txt,
                   regexp_substr(txt, '\d+\$[[:alpha:]]+', 1, level) txt_1,
                   row_number() over(order by regexp_replace(regexp_substr(txt, '\d+\$[[:alpha:]]+', 1, level), '^(\d+)(\$)([[:alpha:]]+)$', '\3')) rn,
                   count(*) over() cnt
            from t1
            connect by level <= length(regexp_replace(txt, '[^\$]', '')))
      connect by rn = prior rn + 1 
      order by level desc)    
where rownum = 1 
16 ноя 10, 14:17    [9787590]     Ответить | Цитировать Сообщить модератору
 Re: Cортировка внутри varchar2  [new]
_Nikotin
Member

Откуда: СПб
Сообщений: 2965
через функцию

drop type str_t;

create type str_t is table of varchar2(64);
/

create or replace function sort_words (i_str varchar2) return varchar2 is
  i pls_integer;
  j pls_integer := 1;
  a number;
  b varchar2(64);
  t str_t := str_t();
  r varchar2(4000);
begin
  loop
    i := instr(i_str, '$', j);
    exit when i = 0 or i is null;
    a := to_number(substr(i_str, j, i - j));
    b := substr(i_str, i+1, a);
    j := i + a + 1;
    t.extend;
    t(t.last) := b;
  end loop;
  for rec in (select column_value from table(t) order by 1) loop
    r := r || length(rec.column_value) || '$' || rec.column_value;
  end loop;
  return r;
end;
/

SQL> with a as
  2  (
  3    select '4$cc$c3$aaa2$bb' a from dual
  4    union all
  5    select '5$acccc3$aaa2$aa' from dual
  6  )
  7  select a, sort_words(a.a)
  8  from a;
 
A                SORT_WORDS(A.A)
---------------- ----------------
4$cc$c3$aaa2$bb  3$aaa2$bb4$cc$c
5$acccc3$aaa2$aa 2$aa3$aaa5$acccc
16 ноя 10, 14:23    [9787630]     Ответить | Цитировать Сообщить модератору
 Re: Cортировка внутри varchar2  [new]
оттакиедела
Guest
Eras,

Не мучайся, это невозможно сделать запросом.
Только модель/функция
16 ноя 10, 14:32    [9787706]     Ответить | Цитировать Сообщить модератору
 Re: Cортировка внутри varchar2  [new]
bdsm_sql
Member

Откуда:
Сообщений: 948
WITH t AS (SELECT '4$сссс3$aaa2$bb' s FROM dual)
SELECT LISTAGG(LENGTH(lx) || '$' || lx) WITHIN GROUP (ORDER BY lx) FROM (
SELECT lex lx FROM (
SELECT lex, d FROM t
MODEL
DIMENSION BY (0 d)
MEASURES (s, 0 x, 0 l, 0 cd, CAST(NULL AS VARCHAR2(2000)) lex)
RULES SEQUENTIAL ORDER ITERATE (1e9) UNTIL (SUBSTR(s[0], iteration_number + 2, 1) IS NULL) (
  l[0] = CASE WHEN SUBSTR(s[0], iteration_number + 1, 1) = '$' THEN x[0] + 1 ELSE l[0] END,
  cd[0] = CASE WHEN SUBSTR(s[0], iteration_number + 1, 1) = '$' THEN cd[0] + 1 ELSE cd[0] END,
  x[0] = CASE WHEN l[0] <= 0 THEN x[0] * 10 + SUBSTR(s[0], iteration_number + 1, 1) ELSE 0 END,
  lex[cd[0]] = lex[cd[0]] || NULLIF(CASE WHEN l[0] > 0 THEN SUBSTR(s[0], iteration_number + 1, 1) END, '$'),
  l[0] = l[0] - 1
)) WHERE d > 0)
16 ноя 10, 14:39    [9787773]     Ответить | Цитировать Сообщить модератору
 Re: Cортировка внутри varchar2  [new]
andrey_anonymous
Member

Откуда: Москва
Сообщений: 18356
bdsm_sql
WITH t AS (SELECT '4$сссс3$aaa2$bb' s FROM dual)

А теперь -
SELECT '4$сссс7$aaa2$bb' s FROM dual
16 ноя 10, 14:44    [9787809]     Ответить | Цитировать Сообщить модератору
 Re: Cортировка внутри varchar2  [new]
bdsm_sql
Member

Откуда:
Сообщений: 948
сенкс!
WITH t AS (SELECT '4$сссс13$XXX$XYYYY$aaa2$bb' s FROM dual)
SELECT LISTAGG(LENGTH(lx) || '$' || lx) WITHIN GROUP (ORDER BY lx) FROM (
SELECT lex lx FROM (
SELECT SUBSTR(lex, 2) lex, d FROM t
MODEL
DIMENSION BY (0 d)
MEASURES (s, 0 x, 0 l, 0 cd, CAST(NULL AS VARCHAR2(2000)) lex)
RULES SEQUENTIAL ORDER ITERATE (1e9) UNTIL (SUBSTR(s[0], iteration_number + 2, 1) IS NULL) (
  cd[0] = CASE WHEN SUBSTR(s[0], iteration_number + 1, 1) = '$' AND l[0] <= 0 THEN cd[0] + 1 ELSE cd[0] END,
  l[0] = CASE WHEN SUBSTR(s[0], iteration_number + 1, 1) = '$' AND l[0] <= 0 THEN x[0] + 1 ELSE l[0] END,
  x[0] = CASE WHEN l[0] <= 0 THEN x[0] * 10 + SUBSTR(s[0], iteration_number + 1, 1) ELSE 0 END,
  lex[cd[0]] = lex[cd[0]] || CASE WHEN l[0] > 0 THEN SUBSTR(s[0], iteration_number + 1, 1) END,
  l[0] = l[0] - 1
)) WHERE d > 0)
16 ноя 10, 14:56    [9787884]     Ответить | Цитировать Сообщить модератору
 Re: Cортировка внутри varchar2  [new]
Maart
Member

Откуда:
Сообщений: 112
Извините. Забыл сказать что версия базы 9.2
16 ноя 10, 15:01    [9787928]     Ответить | Цитировать Сообщить модератору
 Re: Cортировка внутри varchar2  [new]
bdsm_sql
Member

Откуда:
Сообщений: 948
да нам пофигу...
16 ноя 10, 15:07    [9788004]     Ответить | Цитировать Сообщить модератору
 Re: Cортировка внутри varchar2  [new]
bdsm_sql
Member

Откуда:
Сообщений: 948
тогда PL/SQL ф-ция тебе в помощь
16 ноя 10, 15:07    [9788014]     Ответить | Цитировать Сообщить модератору
 Re: Cортировка внутри varchar2  [new]
Maart
Member

Откуда:
Сообщений: 112
В словах могут быть цифры.

Вообще реальная задача немного сложнее.

формат:

<длина имени файла1>$<имя файла1><длина размера файла1>$<размер файла1><длина даты создания файла1>$<дата создания файла1>...<длина имени файлаN>$<имя файлаN><длина размера файлаN>$<размер файлаN><длина даты создания файлаN>$<дата создания файлаN>

Сортировать только по имени файла.
16 ноя 10, 15:12    [9788064]     Ответить | Цитировать Сообщить модератору
 Re: Cортировка внутри varchar2  [new]
bdsm_sql
Member

Откуда:
Сообщений: 948
ну это уже задача по Паскалю.. оракл не при чем
16 ноя 10, 15:30    [9788259]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Oracle Ответить