|
|
|
Задачка, альтернативное решение
|
|||
|---|---|---|---|
|
#18+
Ребята всем привет! Недавно столкнулся вот с такой задачкой: Есть некоторая таблица(отношение) - A , содержащее N-записей(кортежей). Нужно по одному атрибуту для каждого кортежа(записи) провести операцию(рекурсивную), результатом которой станет новое отношение - B , содержащее N-записей. После этого для каждого атрибута таблицы A следует вывести соответствующие ему данные из таблицы B - Т.е. провести операцию соединения. Возможно, я не совсем понятно написал, но надеюсь, что пример сделает задачу более понятной: Дана таблица A : Id Word1ABC2RU Код: plsql 1. 2. 3. 4. 5. 6. Задача - разобрать значение атрибута Word, таблицы A , посимвольно и вывести для атрибута Word каждый соответствующий ему символ. Результат: Id Word Letter1ABCA1ABC B1ABC C2RUR2RUU Решение: Первое: Для разбора значения посимвольно я решил использовать рекурсивынй(иерархический) запрос. Далее просто передаю значения атрибута в этот запрос и получаю его разбор. Можно было это реализовать на PL/SQL: открываем один курсор по таблице А, второй внутри него, который содержит запрос разбора. Но хотелось все-таки на SQL. Втрое: нужно чтобы иерархический запрос разбора работал для конкретного атрибута, а не гулял по всем атрибутам таблицы. Поэтому я решил воспользоваться унарным оператором CONNECT_BY_ROOT. В итоге я пришел вот к такому решению : Код: plsql 1. 2. 3. 4. 5. Но, я потом подумал, а что если бы в таблице не было id!? Возможно я смог бы использовать в качестве уникального идентификатора Rowid? Решил попробовать сначала для одной записи так: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. Отработало все хорошо! Потом решил для всех записей в таблице: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. А здесь получил вот такую ошибку: Код: plsql 1. Товарищи , есть два вопроса к Вам: 1) Можете предложить альтернативное решение задачи? У меня был Oracle 10g 2) Почему возникла ошибка в последнем примере? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.10.2017, 13:03 |
|
||
|
Задачка, альтернативное решение
|
|||
|---|---|---|---|
|
#18+
SQL_boyВ итоге я пришел вот к такому решению : Код: plsql 1. 2. 3. 4. 5. Эту багу прикрыли в 11g: Код: plsql 1. Лучше всего иметь табличную поточную функцию-генератор строк. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.10.2017, 13:30 |
|
||
|
Задачка, альтернативное решение
|
|||
|---|---|---|---|
|
#18+
Никаких rowid Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.10.2017, 14:10 |
|
||
|
Задачка, альтернативное решение
|
|||
|---|---|---|---|
|
#18+
ElicЭту багу прикрыли в 11g: Код: plsql 1. А почему багу? Получается, если на базе сейчас стоит это решение и через какое-то время ее переведу на 11g, то процедура сломается. Да-с, хреново! ElicЛучше всего иметь табличную поточную функцию-генератор строк. Это которая pipelined function ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.10.2017, 14:12 |
|
||
|
Задачка, альтернативное решение
|
|||
|---|---|---|---|
|
#18+
SQL_boyЭто которая pipelined function ?Именно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.10.2017, 14:16 |
|
||
|
Задачка, альтернативное решение
|
|||
|---|---|---|---|
|
#18+
MazoHistНикаких rowid Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. Интересное решение!!! Только одно но! Если встречается одинаковое значение атрибута, то оно уже неправильно отработает! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.10.2017, 14:19 |
|
||
|
Задачка, альтернативное решение
|
|||
|---|---|---|---|
|
#18+
SQL_boyИнтересное решение!!! Только одно но! Если встречается одинаковое значение атрибута, то оно уже неправильно отработает! Ожидал вопрос. Делаем неуникальное уникальным. Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. только потом результат тоже надо как-то разделять будет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.10.2017, 14:26 |
|
||
|
Задачка, альтернативное решение
|
|||
|---|---|---|---|
|
#18+
SQL_boyИнтересное решение!!! Только одно но! Если встречается одинаковое значение атрибута, то оно уже неправильно отработает! connect by prior id/rowid = id/rowid ps другой вопрос если dbms_random.value сгенерит одинаковые значения ..... stax ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.10.2017, 14:33 |
|
||
|
Задачка, альтернативное решение
|
|||
|---|---|---|---|
|
#18+
StaxSQL_boyИнтересное решение!!! Только одно но! Если встречается одинаковое значение атрибута, то оно уже неправильно отработает! connect by prior id/rowid = id/rowid ps другой вопрос если dbms_random.value сгенерит одинаковые значения ..... stax А какая разница? Он же на not null проверяется Код: plsql 1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.10.2017, 14:37 |
|
||
|
Задачка, альтернативное решение
|
|||
|---|---|---|---|
|
#18+
Staxconnect by prior id/rowid = id/rowid ..... stax Он ругается, если использовать rowid. Ошибка, как в первом моем посте. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.10.2017, 14:42 |
|
||
|
Задачка, альтернативное решение
|
|||
|---|---|---|---|
|
#18+
To MazoHist Решение принимается! :) Учитывая, что мое решение работает только на 10g, твое универсальное! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.10.2017, 14:50 |
|
||
|
Задачка, альтернативное решение
|
|||
|---|---|---|---|
|
#18+
SQL_boyStaxconnect by prior id/rowid = id/rowid ..... stax Он ругается, если использовать rowid. Ошибка, как в первом моем посте. Ну нету rowid у сгенерированных таким образом записей - они же не сохранены в таблице. Сложите в табличку - будет rowid. Если on-fly - то используйте вместо rowid любой нумератор, хоть rownum. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.10.2017, 14:53 |
|
||
|
Задачка, альтернативное решение
|
|||
|---|---|---|---|
|
#18+
SQL_boy To MazoHist Решение принимается! Вот это: Код: plsql 1. печальная тема. Воспользуйтесь лучше рекурсивным with subquery clause. Другой вариант - сгенерировать нужное число строк (как максимальную длину строки) и соединить с исходной таблицей. Еще лучше - опереться на любую имеющуюся таблицу, содержащую более 4000 строк. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.10.2017, 14:56 |
|
||
|
Задачка, альтернативное решение
|
|||
|---|---|---|---|
|
#18+
SQL_boyStaxпропущено... connect by prior id/rowid = id/rowid ps другой вопрос если dbms_random.value сгенерит одинаковые значения ..... stax А какая разница? Он же на not null проверяется Код: plsql 1. Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. SQL_boyStaxconnect by prior id/rowid = id/rowid ..... stax Он ругается, если использовать rowid. Ошибка, как в первом моем посте. потому что у вью (with) нет ровіда Код: 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. ..... stax ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.10.2017, 15:00 |
|
||
|
Задачка, альтернативное решение
|
|||
|---|---|---|---|
|
#18+
andrey_anonymousДругой вариант - сгенерировать нужное число строк (как максимальную длину строки) и соединить с исходной таблицей. Еще лучше - опереться на любую имеющуюся таблицу, содержащую более 4000 строк.Ещё лучше лучшего - коррелированный table(), чтобы не генерить лишних строк декартом, чтобы потом с ними не бороться. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.10.2017, 15:02 |
|
||
|
Задачка, альтернативное решение
|
|||
|---|---|---|---|
|
#18+
ElicЕще лучше - опереться на любую имеющуюся таблицу, содержащую более 4000 строк.Ещё лучше лучшего - коррелированный table(), чтобы не генерить лишних строк декартом, чтобы потом с ними не бороться.[/quot] Ну дальше пойдут lateral, а там и модели подтянутся :) От условий зависит. Вот вчера разговаривал с коллегой, у которого есть задача сделать некое решение, пригодное к переносу на PGSql. Так рекурсивный with в его условиях - самое оно. А кто-то, возможно, имеет ввиду какой-нибудь убогий опенсорс, не умеющий деревяшку al all - ему cartesian join с таблицей о 4000 строках показан. Ну а ежели товарищу именно под oracle - то я бы сделал pipelined и не парил никому мозг. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.10.2017, 15:08 |
|
||
|
Задачка, альтернативное решение
|
|||
|---|---|---|---|
|
#18+
andrey_anonymousпригодное к переносу на PGSql.... а в киеве дядько. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.10.2017, 15:09 |
|
||
|
Задачка, альтернативное решение
|
|||
|---|---|---|---|
|
#18+
To Stax , Я изначально не совсем правильно понял назначение: Код: plsql 1. поэтому так написал. Сейчас понимаю, что здесь работает все иначе. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.10.2017, 15:11 |
|
||
|
Задачка, альтернативное решение
|
|||
|---|---|---|---|
|
#18+
Elic, andrey_anonymous Что за коррелированный table() и lateral? Модели это которое MODEL DIMENSION BY и т.д.? ))) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.10.2017, 15:21 |
|
||
|
Задачка, альтернативное решение
|
|||
|---|---|---|---|
|
#18+
SQL_boy, WITH a as ( SELECT COLUMN_VALUE AS Word FROM TABLE(sys.odcivarchar2list('ABC', 'RU')) ) SELECT a.word, SUBSTR(word, b.rn, 1) letter FROM a, LATERAL(SELECT LEVEL rn FROM dual CONNECT BY LEVEL<=LENGTH(a.word)) b ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.10.2017, 20:58 |
|
||
|
Задачка, альтернативное решение
|
|||
|---|---|---|---|
|
#18+
One more: WITH y(rn, word, letter, i) AS ( SELECT ROWNUM rn, COLUMN_VALUE word, SUBSTR(COLUMN_VALUE, 1, 1), 1 FROM TABLE(sys.odcivarchar2list('ABC', 'RU')) UNION ALL SELECT rn, word, SUBSTR(word, y.i+1, 1), y.i+1 FROM y WHERE rn=y.rn AND SUBSTR(word, y.i+1, 1) IS NOT NULL ) SELECT word, letter FROM y ORDER BY rn, i ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.10.2017, 21:13 |
|
||
|
Задачка, альтернативное решение
|
|||
|---|---|---|---|
|
#18+
And yet one more: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.10.2017, 21:19 |
|
||
|
Задачка, альтернативное решение
|
|||
|---|---|---|---|
|
#18+
SQL_boy, the MODEL Clause: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.10.2017, 22:08 |
|
||
|
Задачка, альтернативное решение
|
|||
|---|---|---|---|
|
#18+
Zahar H.SQL_boy, the MODEL Clause: Ну и зачем итерации: Код: 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. 30. 31. SY. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.10.2017, 23:19 |
|
||
|
|

start [/forum/topic.php?fid=52&msg=39541805&tid=1885036]: |
0ms |
get settings: |
9ms |
get forum list: |
20ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
157ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
89ms |
get tp. blocked users: |
1ms |
| others: | 218ms |
| total: | 515ms |

| 0 / 0 |
