Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Обратная функция по отношению к listagg / 25 сообщений из 31, страница 1 из 2
23.05.2013, 18:57
    #38270719
Обратная функция по отношению к listagg
Добрый день всем!

Есть вопрос:

Допустим у меня есть такой набор данных:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
field1 (int)       full_path (varchar2)

3242             ,3242,  
104550           ,3242,104550,
146951           ,3242,146951,
14               ,3242,146951,14,
15               ,3242,146951,14,15 



короче говоря field1 - это уникальный ID записи, а full_path - полный путь этой записи в дереве.

Из этого набора необходимо получить такое:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
field2 (int)       field3 (int)

3242             3242  

104550           3242
104550           104550

146951           3242
146951           146951

14               3242
14               146951
14               14 

15               3242
15               146951
15               14 
15               15



то есть, если допустить, что первый набор был получен при помощи listagg (хотя это не так и использовалась sys_connect_by_path)
то в данном случае нужно обратно всё "разгруппировать".

Есть ли какое-то решение ?

Да, исходный набор данных в таблице выглядит так:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
id, parent_id

3242     NULL
104550   3242
146951   3242
14       146951
15       14




Спасибо!
...
Рейтинг: 0 / 0
23.05.2013, 19:02
    #38270724
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обратная функция по отношению к listagg
Станислав БабинЕсть ли какое-то решение ?
Да: не создавать самому себе трудности и сразу использовать иерархические запросы для
получения нужного результата прямо из исходного набора данных. Без промежуточных
извращений с listagg.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
23.05.2013, 19:06
    #38270731
Обратная функция по отношению к listagg
Dimitry SibiryakovСтанислав БабинЕсть ли какое-то решение ?
Да: не создавать самому себе трудности и сразу использовать иерархические запросы для
получения нужного результата прямо из исходного набора данных. Без промежуточных
извращений с listagg.


Можете ли составить текст запроса для приведенного примера?
Изначальный набор данных 3, нужно получить набор данных 2.
...
Рейтинг: 0 / 0
23.05.2013, 19:25
    #38270749
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обратная функция по отношению к listagg
Станислав БабинМожете ли составить текст запроса для приведенного примера?

Могу, но зачем оно мне? RTFM connect by или with recursive, студент.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
23.05.2013, 19:37
    #38270759
Lecter
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обратная функция по отношению к listagg
Станислав Бабин,

connect by + regexp_substr спасут отца русской демократии.
...
Рейтинг: 0 / 0
23.05.2013, 19:52
    #38270786
-2-
-2-
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обратная функция по отношению к listagg
Lecterconnect by + regexp_substr connect by + union all
...
Рейтинг: 0 / 0
23.05.2013, 19:57
    #38270800
Обратная функция по отношению к listagg
-2-Lecterconnect by + regexp_substr connect by + union all
Код: plsql
1.
select connect_by_root id, id from t connect by id = prior parent_id;
...
Рейтинг: 0 / 0
23.05.2013, 20:34
    #38270845
-2-
-2-
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обратная функция по отношению к listagg
Тряхнём перечницей,

да, про union я перемудрил с равенством паренту.
...
Рейтинг: 0 / 0
23.05.2013, 20:41
    #38270852
stax..
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обратная функция по отношению к listagg
Станислав Бабин,
мона по старинке вместо connect by "pivot" фурумный
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
  1  WITH t AS
  2  (SELECT 1 id ,',1234,567,89,0' str FROM dual union all
  3   SELECT 2 id ,',asdf,dfg,fg,g' str FROM dual
  4  )
  5  select id,
  6   substr(str,
  7           instr(str, ',', 1, level)+1
  8         , instr(str||',', ',', 1, level+1)-instr(str, ',', 1, level)-1) s
  9    from t /*, pivot  ....*/
 10  connect by level <= length(trim(str)) - length(trim(replace(str, ',')))
 11   and id = prior id
 12   and prior DBMS_RANDOM.VALUE IS NOT NULL
 13* order by 1
SQL> /

        ID S
---------- --------------
         1 1234
         1 567
         1 89
         1 0
         2 asdf
         2 dfg
         2 fg
         2 g

8 rows selected.




ps
несколько напрягает DBMS_RANDOM.VALUE
....
stax
...
Рейтинг: 0 / 0
23.05.2013, 20:56
    #38270867
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обратная функция по отношению к listagg
stax..Станислав Бабин,
несколько напрягает DBMS_RANDOM.VALUE


Посему надежней SYS_GUID().

SY.
...
Рейтинг: 0 / 0
23.05.2013, 21:36
    #38270897
stax..
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обратная функция по отношению к listagg
SYstax..Станислав Бабин,
несколько напрягает DBMS_RANDOM.VALUE


Посему надежней SYS_GUID().

SY.

спасиб

я пользую/пользовал табличку "pivot" c 10000 записями

....
stax
...
Рейтинг: 0 / 0
23.05.2013, 21:48
    #38270911
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обратная функция по отношению к listagg
Если производительность особо не напрягает:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
WITH t AS (
           SELECT 1 id ,',1234,567,89,0' str FROM dual union all
           SELECT 2 id ,',asdf,dfg,fg,g' str FROM dual
          )
select  id,
        s
  from  t,
        xmltable(
                 'ora:tokenize($s,",")'
                 passing ltrim(str,',') as "s"
                 columns
                   s varchar2(20) path '.'
                )
/

        ID S
---------- -----
         1 1234
         1 567
         1 89
         1 0
         2 asdf
         2 dfg
         2 fg
         2 g

8 rows selected.

SQL> 



SY.
...
Рейтинг: 0 / 0
24.05.2013, 10:03
    #38271354
Обратная функция по отношению к listagg
SY,

Спасибо за помощь.
...
Рейтинг: 0 / 0
16.12.2013, 12:28
    #38501982
Обратная функция по отношению к listagg
Станислав Бабин, Аналогичный пример с использованием рекурсивного запроса
--':p1 12 45 68'
with q1(wx,n) as
(select substr(:p1,1,INSTR(:p1,' ',1,1)-1) , 1 as n from dual
union all
select substr(:p1,INSTR(:p1,' ',1,n)+1,
case when INSTR(:p1,' ',1,n+1)>0 then
INSTR(:p1,' ',1,n+1)-1-INSTR(:p1,' ',1,n)
else
length(:p1)-INSTR(:p1,' ',1,n)
end
)
, n+1 as n from q1
where INSTR(:p1,' ',1,n)>0
)
select wx from q1
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
16.06.2015, 15:00
    #38984892
Ryuu
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обратная функция по отношению к listagg
Есть ли более изящное решение, с использованием xml, чтобы не было ошибки, в случае, если у нас нет разделителя и строчку в общем-то разбивать не нужно?
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
WITH t1 AS
  ( SELECT 1 id ,'1234 567 89 0' str FROM dual
  UNION ALL
  SELECT 2 id ,'asdf dfg fg g' str FROM dual
  UNION ALL
  SELECT 3 id , 'gg' str FROM dual
  UNION ALL
  SELECT 4 id , NULL str FROM dual
  )
SELECT id,
  s
FROM
  (SELECT id,
    (
    CASE
      WHEN instr(str, ' ') = 0
      THEN '666 '
        ||str
      ELSE str
    END) AS str
  FROM t1
  ) t1,
  xmltable( 'ora:tokenize($s," ")' passing ltrim(str,' ') AS "s" columns s VARCHAR2(20) path '.' )
WHERE s!='666';
...
Рейтинг: 0 / 0
16.06.2015, 15:36
    #38984934
-2-
-2-
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обратная функция по отношению к listagg
RyuuЕсть ли более изящное решениенаписать/позаимствовать функцию.

Ryuuчтобы не было ошибки, в случае, если у нас нет разделителяпредконкатенация с разделителем или if match внутри xquery
...
Рейтинг: 0 / 0
16.06.2015, 15:36
    #38984935
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обратная функция по отношению к listagg
Код: plsql
1.
select * from t1, xmltable(nvl(rtrim(regexp_replace(str||' ', '(\S+)\s+', '"\1",'), ', '), '1 to 0'))
...
Рейтинг: 0 / 0
17.06.2015, 10:04
    #38985440
Ryuu
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обратная функция по отношению к listagg
Elic, хмм, 12 оракл? У меня не работает, 11. Причем код ошибки не пишет.
...
Рейтинг: 0 / 0
17.06.2015, 10:13
    #38985451
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обратная функция по отношению к listagg
Ryuu12 оракл? У меня не работает, 11 http://www.bugtraq.ru/forum/faq/general/smart-questions.html] RTFM
Работает как минимум начиная с 11.2.0.3.

P.S. В 11.2.0.2 XML-движок был коренным образом заменён.
...
Рейтинг: 0 / 0
17.06.2015, 10:13
    #38985452
Обратная функция по отношению к listagg
Ryuu,

все работает на 11g. пробей тчательнее.
...
Рейтинг: 0 / 0
17.06.2015, 10:34
    #38985480
Ryuu
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обратная функция по отношению к listagg
х3, у меня Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production и выдает это

Видимо админы окончательно поломали базу... В любом случае, это я так, для общего развития, так что и бог с ним.
...
Рейтинг: 0 / 0
17.06.2015, 10:42
    #38985492
Ryuu
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обратная функция по отношению к listagg
Спасибо.
...
Рейтинг: 0 / 0
17.06.2015, 10:46
    #38985500
Обратная функция по отношению к listagg
RyuuВидимо админы окончательно поломали базу....для начала как минимум смотреть статус компонент:
Код: plsql
1.
2.
select comp_name, version, status, modified
from dba_registry


Дальше думать...
Если ставили патч, то компоненты должны соответствовать версии патча и иметь стату VALID
...
Рейтинг: 0 / 0
17.06.2015, 10:55
    #38985512
Ryuu
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обратная функция по отношению к listagg
У меня нет прав даже на просмотр данной таблицы. :)
...
Рейтинг: 0 / 0
17.06.2015, 14:26
    #38985842
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обратная функция по отношению к listagg
Elic
Код: plsql
1.
select * from t1, xmltable(nvl(rtrim(regexp_replace(str||' ', '(\S+)\s+', '"\1",'), ', '), '1 to 0'))



1. Возвращаемое XMLTABLE поле COLUMN_VALUE имеет тип XMLTYPE, так-что лучше XMLCAST(COLUMN_VALUE AS VARCHAR2(размер))
2. При условии str не содержит кавычек (одинарных и двойных), амперсандов и.т.д.

В общем случае что-то типа:

Код: plsql
1.
2.
3.
select t1.*,dbms_xmlgen.convert(xmlcast(column_value as varchar2(10)),1) column_value
 from t1, xmltable(nvl(rtrim(regexp_replace(dbms_xmlgen.convert(str)||' ', '(\S+)\s+', '"\1",'), ', '), '1 to 0')) x
/



SY.
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Обратная функция по отношению к listagg / 25 сообщений из 31, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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