Гость
Форумы / Oracle [игнор отключен] [закрыт для гостей] / В произвольной строке, состоящей из символьных элементов, отсортировать записи / 16 сообщений из 16, страница 1 из 1
11.12.2019, 16:07
    #39901339
Dreadisback
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
В произвольной строке, состоящей из символьных элементов, отсортировать записи
Вопрос похож по содержанию на вот этот: Как отсортировать элементы в строке по алфавиту с помощью раздела model язык oracle sql

Задание абсолютно идентичное, с одной поправкой - раздел model и аналитические функции использовать нельзя, и добавляется порядок сортировки:

В произвольной строке, состоящей из символьных
элементов, разделенных запятыми, отсортировать элементы по
алфавиту.


При этом сначала идут строчные символы, затем прописные (очевидно и те и те в порядке алфавита), затем цифры по возрастанию, затем пробелы и пустые строки (пустые строки задаются просто двумя запятыми - abc,,asd,sd - пример строки с пустым элементом)
Алфавит - латинский + все цифры и спецсимволы
Пример результата:

Input: abc,cde,ef,gh,mn,test,ss,df,fw,ewe,wwe
Sorted string: abc,cde,df,ef,ewe,fw,gh,mn,ss,test,wwe

Более сложный и содержательный пример:

Input: ab7c,abc,9aH,9a7,8A,cDe,-a-,ef,9gh,mn,TEST,-*ss,TE(f,fw,ewe,, ,wwe

Sorted string: abc,ab7c,cDe,ef,ewe,fw,mn,wwe,TEST,TE(f,8A,9aH,9a7,9gh,-a-,-*ss,, ,

По факту тут нужно посимвольно сравнивать элементы, и в зависимости от приоритета их сортировать. Загвоздка в том, что Oracle сортирует элементы в порядке - сначала спецсимволы, затем А а B b C c - затем цифры, конечно, это зависит от локали, но менять ее нельзя, возможно можно использовать NLSSORT, но я не нашел стандарта в котором он сортирует так как мне нужно.
Вообще, так как это университетское задание - желательная реализация в основном опирающаяся на иерархические запросы и регулярные выражения - как сказано выше, аналитические функции использовать запрещено. Но интересно будет взглянуть на любые правильные решения.

Вот пока до чего я дошел, на первый взгляд работает верно, то есть ряд нюансов:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
WITH TEXT AS
            (SELECT 'ab7c,abc,9aH,9a7,8A,cDe,-a-,ef,9gh,mn,TEST,-*ss,TE(f,fw,ewe,, ,wwe' STR
            FROM DUAL),
WORDS AS (SELECT REGEXP_SUBSTR(STR,'(([^,]+)?,)|([^,]+$)' ,1,LEVEL) PARTS
            FROM TEXT
            CONNECT BY LEVEL<=REGEXP_COUNT(STR,'(([^,]+)?,)|([^,]+$)')
            ),
OMG AS (SELECT PARTS
        FROM WORDS
        ORDER BY RPAD(REGEXP_SUBSTR(PARTS,'^[a-z]+',1,1,'c'),(SELECT MAX(LENGTH(PARTS)) FROM WORDS), '0'),
        RPAD(REGEXP_SUBSTR(PARTS,'^[A-Z]+',1,1,'c'),(SELECT MAX(LENGTH(PARTS)) FROM WORDS), '0'),
        REGEXP_SUBSTR(PARTS,'^[0-9]+'),REGEXP_SUBSTR(PARTS,'^[^[:alnum:], ]+'),
        RPAD( REGEXP_SUBSTR(PARTS,'[a-z]+',1,1,'c'),(SELECT MAX(LENGTH(PARTS)) FROM WORDS), '0'),
        RPAD( REGEXP_SUBSTR(PARTS,'[A-Z]+',1,1,'c'),(SELECT MAX(LENGTH(PARTS)) FROM WORDS), '0')),
NUMOMG AS (SELECT SUBSTR(REGEXP_REPLACE(PARTS,',',' '),1,LENGTH(REGEXP_REPLACE(PARTS,',',' '))-1) W, ROWNUM RN
            FROM OMG)
SELECT LTRIM(SYS_CONNECT_BY_PATH(W,','),',') SORTED_STRING
FROM NUMOMG
WHERE RN=(SELECT COUNT(*) FROM WORDS)
START WITH RN=1
CONNECT BY LEVEL =RN;



Вроде работает, прошу поломать, так сказать ))
Очень приветствуются другие решения (особенно в рамках правил) и советы, идеи как еще можно это реализовать
...
Рейтинг: 0 / 0
11.12.2019, 16:28
    #39901352
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
В произвольной строке, состоящей из символьных элементов, отсортировать записи
Dreadisback
Вроде работает
Задача "собрать обратно" решена максимум на "зачёт".
...
Рейтинг: 0 / 0
11.12.2019, 16:37
    #39901358
Dreadisback
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
В произвольной строке, состоящей из символьных элементов, отсортировать записи
Elic, да, есть с этим определенные проблемы. Вообще изначально планировал собрать listaggом, но почему то при его использовании порядок записей нарушается.
И вероятно это даже не "зачет" - а сразу можно прыгать в сапоги.
Но на данный момент интересует именно сортировка, задача "собрать обратно" миллион раз уже описана на этом форуме и не только, так что думаю справлюсь поприличнее, когда припрет.
...
Рейтинг: 0 / 0
11.12.2019, 17:08
    #39901370
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
В произвольной строке, состоящей из символьных элементов, отсортировать записи
Dreadisback,

listagg в новых версиях научилась сортировать

.....
stax
...
Рейтинг: 0 / 0
11.12.2019, 17:20
    #39901374
Dreadisback
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
В произвольной строке, состоящей из символьных элементов, отсортировать записи
Stax,
А можно ли собрать записи listaggом без сортировки?

То есть: select listagg(exprs) within group (order by ?)
from table1

Чтобы порядок был такой же, как и в таблице/подзапросе из которого выбираются записи?
...
Рейтинг: 0 / 0
11.12.2019, 18:56
    #39901429
Кобанчег
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
В произвольной строке, состоящей из символьных элементов, отсортировать записи
Dreadisback
При этом сначала идут строчные символы, затем прописные (очевидно и те и те в порядке алфавита), затем цифры по возрастанию, затем пробелы и пустые строки (пустые строки задаются просто двумя запятыми - abc,,asd,sd - пример строки с пустым элементом)
Алфавит - латинский + все цифры и спецсимволы
Ничего не указано про приоритет спец символов. Если допустить что он выше чем у пробельных символов - всё равно непонятно почему в результате пробел идёт после пустого элемента.
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
with t as (select 1 as id, 'ab7c,abc,9aH,9a7,8A,cDe,-a-,ef,9gh,mn,TEST,-*ss,TE(f,fw,ewe,, ,wwe' as s from dual)
, z as
(select listagg(chr(l)) within group (order by l) str1, listagg(chr(l)) within group (order by ord) str2
   from (select level l,
                row_number() over (order by length(regexp_replace(chr(level), '([a-z])|([A-Z])|(\d)|(\S)|(\s)',
                                                                              '\1\2\2\3\3\3\4\4\4\4\5\5\5\5\5')), level) ord
           from dual connect by level <= 255))
select id, xmlagg(xmlelement("x", c, ',') order by nlssort(translate(c, str2, str1), 'NLS_SORT = Binary') nulls last).extract('//x/text()') s0
  from t, z, xmltable('tokenize(.,",")' passing t.s columns c varchar2(30) path '.') x
group by id
order by id;

        ID S0
---------- ----------------------------------------------------------------------
         1 abc,ab7c,cDe,ef,ewe,fw,mn,wwe,TEST,TE(f,8A,9aH,9a7,9gh,-a-,-*ss, ,,
...
Рейтинг: 0 / 0
11.12.2019, 19:04
    #39901433
Кобанчег
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
В произвольной строке, состоящей из символьных элементов, отсортировать записи
Если аналитику использовать нельзя, то row_number можно получить с помощтю self join/scalar subquery.
Или вообще можно захардкодить str1 и str2, но это не от большого ума.
...
Рейтинг: 0 / 0
11.12.2019, 19:11
    #39901438
Кобанчег
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
В произвольной строке, состоящей из символьных элементов, отсортировать записи
Dreadisback
прошу поломать, так сказать
Код: plsql
1.
SELECT 'TEST,TE+T,TE T' STR
...
Рейтинг: 0 / 0
11.12.2019, 20:10
    #39901483
Dreadisback
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
В произвольной строке, состоящей из символьных элементов, отсортировать записи
Кобанчег
Ничего не указано про приоритет спец символов. Если допустить что он выше чем у пробельных символов - всё равно непонятно почему в результате пробел идёт после пустого элемента.


Да, неправильный пример привел, сейчас исправлю
Приоритет спецсимволов относительно друг друга неважен, пробел в идеале должен идти после спецсимволов - затем пустые строки

Спасибо за предложенное решение, сейчас буду сидеть разбираться ))
...
Рейтинг: 0 / 0
11.12.2019, 21:43
    #39901521
Кобанчег
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
В произвольной строке, состоящей из символьных элементов, отсортировать записи
Dreadisback
Приоритет спецсимволов относительно друг друга неважен
Это абсурд. То есть неважно идет + потом - или наоборот?
Речь вообще шла не про приоритет спецсимволов относительно друг друга, а про их приоритет относительно пробельных симповлов.
Dreadisback
Спасибо за предложенное решение, сейчас буду сидеть разбираться ))
Там все очень тривиально.
Символы разбиваются на группы строчные/прописные/цифры/спец/пробельные
и упорядочиваются с учетом приоритета группы (от 1 до 5) и в рамках группы учитывая исходный порядок.
Потом в сортировке используется строка переведенная с учетом нового порядка.

PS.
Я так понимаю дебильные скобочки в конце предложения это признак молодого поколения.
В дипломе тоже планируешь в таком стиле писать?
...
Рейтинг: 0 / 0
11.12.2019, 21:53
    #39901528
Valergrad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
В произвольной строке, состоящей из символьных элементов, отсортировать записи
Кобанчег

PS.
Я так понимаю дебильные скобочки в конце предложения это признак молодого поколения.
В дипломе тоже планируешь в таком стиле писать?


Неспособность отличить дипломную работу от сообщения на форуме - это признак какого поколения?
...
Рейтинг: 0 / 0
11.12.2019, 23:49
    #39901570
Кобанчег
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
В произвольной строке, состоящей из символьных элементов, отсортировать записи
Valergrad
Неспособность отличить дипломную работу от сообщения на форуме - это признак какого поколения?
Вероятно это твоя личная проблема раз ты об этом заговорил.

Ты тоже ситаешь что скобочка это дружелюбная точка?
...
Рейтинг: 0 / 0
12.12.2019, 00:56
    #39901574
Dreadisback
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
В произвольной строке, состоящей из символьных элементов, отсортировать записи
Кобанчег, премного благодарен, сейчас появилось время разобрать ваше решение - все именно так, как нужно, спасибо.
Только сборку xml переделал listagом, но думаю разница невелика.

Хороший прием смены порядка символов в сортировке с помощью translate, уже находил его где-то и поначалу так и хотел сделать, но из-за собственной интеллектуальной несостоятельности не смог сообразить как изменить порядок символов в таблице ASCII.

А по поводу скобок в конце предложения - стилистика электронных переписок не стоит на месте, так что привыкайте, сударь, даже если такой формат вам нравится.
...
Рейтинг: 0 / 0
12.12.2019, 01:34
    #39901582
Кобанчег
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
В произвольной строке, состоящей из символьных элементов, отсортировать записи
Dreadisback
Только сборку xml переделал listagом, но думаю разница невелика.
listagg съедает пустые строки (в отличие от xmlagg), так что придётся сделать финт ушами, чтоб этого не происходило.
...
Рейтинг: 0 / 0
12.12.2019, 10:51
    #39901721
Dreadisback
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
В произвольной строке, состоящей из символьных элементов, отсортировать записи
Кобанчег, да, пока после listagg добил RPADом строку запятыми до длины входящей строки - вроде ни при каких тестовых значениях пока элементы не терялись.
...
Рейтинг: 0 / 0
12.12.2019, 18:27
    #39902082
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
В произвольной строке, состоящей из символьных элементов, отсортировать записи
Dreadisback
Stax,
А можно ли собрать записи listaggом без сортировки?

То есть: select listagg(exprs) within group (order by ?)
from table1

Чтобы порядок был такой же, как и в таблице/подзапросе из которого выбираются записи?


порядок ж в подзапросе как-то ж формируется

имхо rownum будет достаточно
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
  1  select
  2    listagg(deptno||job, ',') within group(order by rownum) code_list
  3* from (select * from emp order by deptno,job) e
  4  /

CODE_LIST
--------------------------------------------------------------------------------
10CLERK,10MANAGER,10PRESIDENT,20ANALYST,20ANALYST,20CLERK,20CLERK,20MANAGER,30CL
ERK,30MANAGER,30SALESMAN,30SALESMAN,30SALESMAN,30SALESMAN



....
stax
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / В произвольной строке, состоящей из символьных элементов, отсортировать записи / 16 сообщений из 16, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]