Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Рекурсия
|
|||
|---|---|---|---|
|
#18+
Добрый день. Задачка такая: Есть таблица адресов с полями id, adress, formalname, level, parent_id. Parent_id ссылается на id из этой же таблицы. id adress formalname level parent_id 1 630123, Новосибирская обл, Новосибирск г, Петухова ул Петухова ул 33 2 2 630123, Новосибирская обл, Новосибирск г Новосибирск г 22 3 3 630123, Новосибирская обл Новосибирская обл 11 null В итоге должна получиться таблица: id adress Index 11 22 33 1 630123, Новосибирская обл, Новосибирск г, Петухова ул 630123 Новосбирская обл Новосбирск г Петухова ул Индекса в поле adress может и не быть. Получается нужно разбить адрес по уровням level, ссылаясь на родителя. Тут простым запросом не обойдешься, наверное, нужно писать какую-то процедуру, чего я пока не делала. Подскажите, пожалуйста, в каком направлении нужно действовать, что почитать, с чего начать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.12.2018, 17:02 |
|
||
|
Рекурсия
|
|||
|---|---|---|---|
|
#18+
в первом сообщении не понятно как по столбцам разбивается таблица, немного исправила. Есть таблица адресов с полями id, adress, formalname, level, parent_id. Parent_id ссылается на id из этой же таблицы. id | adress | formalname | level | parent_id 1 | 630123, Новосибирская обл, Новосибирск г, Петухова ул | Петухова ул | 33 | 2 2 | 630123, Новосибирская обл, Новосибирск г | Новосибирск г | 22 | 3 3 | 630123, Новосибирская обл | Новосибирская обл | 11 | null В итоге должна получиться таблица: id | adress | Index | 11 | 22 | 33 1 | 630123, Новосибирская обл, Новосибирск г, Петухова ул | 630123 | Новосбирская обл | Новосбирск г | Петухова ул ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.12.2018, 17:10 |
|
||
|
Рекурсия
|
|||
|---|---|---|---|
|
#18+
*Ann*, Для начала почитайте про рекурсивный CTE. Глядишь, и процедуру писать не понадобиться... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.12.2018, 20:21 |
|
||
|
Рекурсия
|
|||
|---|---|---|---|
|
#18+
Почитала про рекурсивные cte, во всех статьях примеры с выводом дерева в столбик. А мне надо строкой, при этом каждый элемент поместить с столбец в зависимости от уровня level. При этом количество уровней может быть разное. Может быть например 1,2 3 уровень, а может быть 1,3,4 уровень, тогда столбец со вторым уровнем должен быть пустым. Есть какие-то примеры с выводом дерева в строку? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.12.2018, 05:31 |
|
||
|
Рекурсия
|
|||
|---|---|---|---|
|
#18+
*Ann*, Возможно, вам нужно такое ... Если же задача всё таки стоит в отдельные столбцы, а не просто одной строкой - то тут прямая дорога к динамическому SQL. А в вашем конкретном случае - сначала вертикальный сбор дерева посредством рекурсивного СТЕ, затем его разворот в строку при помощи динамического PIVOT-а ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.12.2018, 06:54 |
|
||
|
Рекурсия
|
|||
|---|---|---|---|
|
#18+
*Ann*, если я правильно понял вы хотите из этого id adress formalname levelparent_id1 630123 Новосибирская обл. Новосибирск г. Петухова ул Петухова ул 33 22 630123 Новосибирская обл. Новосибирск г Новосибирск г 22 33 630123 Новосибирская обл Новосибирская обл 11 null собирать это id adress index formalname1 formalname2 formalnameN1 630123 Новосибирская обл. Новосибирск г. Петухова ул 630123 Новосбирская обл Новосбирск г Петухова ул хотя полный адрес у вас есть в первой же строке в поле adress, части адреса в полях formalname, и у вас нет нигде индекса как отдельный атрибут Мне кажется тут нужны некоторые пререквизиты. Вам надо определиться с количеством уровней результирующей таблицы. SQL не может выдать вам строки с произвольным количеством атрибутов, поэтому вам надо понять сколько уровней разбиения адреса у вас есть в базе. Если это всегда четыре (индекс, область/регион, город, улица) то можно будет сделать обычный запрос. Если это более сложное динамическое деление, то вам надо понять по каким признакам вы будете размещать части вашего адреса, иначе у вас в разные колонки пойдут разные данные: id adress index formalname1 formalname2 formalnameN1 630123 Новосибирская обл. Новосибирск г. Петухова ул 630123 Новосбирская обл Новосбирск г Петухова ул2 Московская обл. Москва г. Ленина ул Московская обл Москва г Ленина ул1 Татарстан. Агрызский район. Васильево пгт. Ленина ул Татарстан Агрызский районВасильево пгт Ленина ул В любом случае, учитывая *Ann*Индекса в поле adress может и не быть. вам придется определиться с тем, как обрабатывать подобные случаи. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.12.2018, 08:24 |
|
||
|
Рекурсия
|
|||
|---|---|---|---|
|
#18+
PizzaPizza, Уровней всего 9. Если родителя какого-то уровня нет, то ячейку надо пропустить. Уровень указан в поле level. Если нет индекса, то ячейка тоже должна остаться пустой. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.12.2018, 10:13 |
|
||
|
Рекурсия
|
|||
|---|---|---|---|
|
#18+
как-то так Код: sql 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. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.12.2018, 10:44 |
|
||
|
Рекурсия
|
|||
|---|---|---|---|
|
#18+
*Ann*PizzaPizza, Уровней всего 9. Если родителя какого-то уровня нет, то ячейку надо пропустить. Уровень указан в поле level. Если нет индекса, то ячейка тоже должна остаться пустой. Если у вас всегда четко 9 уровней, то сделайте на 9ти джойнах например. Выберете все записи первого уровня и к ним присоединяйте self join Id=parent_id и следующий уровень, а к нему уже по Id=parent_id-предыдущего уровня и так 9 раз. А потом отдельно поиск индекса по каким то правилам в подстроке и формируете запись. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.12.2018, 21:01 |
|
||
|
Рекурсия
|
|||
|---|---|---|---|
|
#18+
PizzaPizza*Ann*PizzaPizza, Уровней всего 9. Если родителя какого-то уровня нет , то ячейку надо пропустить. Уровень указан в поле level. Если нет индекса, то ячейка тоже должна остаться пустой. Если у вас всегда четко 9 уровней, то сделайте на 9ти джойнах например. Выберете все записи первого уровня и к ним присоединяйте self join Id=parent_id и следующий уровень, а к нему уже по Id=parent_id-предыдущего уровня и так 9 раз. А потом отдельно поиск индекса по каким то правилам в подстроке и формируете запись. И в каждом последующем ты будешь писать [id_parent] = COALESCE( tn.[id], tn-1.[id],... ) ? Сумасошел? Пойди выспись! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.12.2018, 10:00 |
|
||
|
Рекурсия
|
|||
|---|---|---|---|
|
#18+
Руслан Дамирович, При запуске запроса выдаётся сообщение о том, что cte не существует. Мне кажется, ругается на второй select. У меня используется postgresql, но вряд ли это влияет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2019, 06:49 |
|
||
|
Рекурсия
|
|||
|---|---|---|---|
|
#18+
*Ann*При запуске запроса выдаётся сообщение о том, что cte не существует. Мне кажется, ругается на второй select. У меня используется postgresql, но вряд ли это влияет.Думаю, у вас в коде ошибка. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2019, 08:09 |
|
||
|
Рекурсия
|
|||
|---|---|---|---|
|
#18+
Подскажите, пожалуйста, postgresql не поддерживает квадратные скобки? С ними скрипт не работает. Если их убирать, то тогда как обозначить lvl =1? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.01.2019, 05:06 |
|
||
|
Рекурсия
|
|||
|---|---|---|---|
|
#18+
Убрала скобки, заменила названия полей и таблиц, в коде ничего не меняла, все равно выдается сообщение о том, что cte не существует (см. файл). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.01.2019, 09:52 |
|
||
|
Рекурсия
|
|||
|---|---|---|---|
|
#18+
*Ann*Подскажите, пожалуйста, postgresql тут века не по postgres , а MS SQL ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.01.2019, 10:22 |
|
||
|
Рекурсия
|
|||
|---|---|---|---|
|
#18+
*Ann*, ошибка в cte, вы ее еще не создали, а после union all ее же и используете ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.01.2019, 10:47 |
|
||
|
Рекурсия
|
|||
|---|---|---|---|
|
#18+
Код: sql 1. откуда им взяться? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.01.2019, 10:50 |
|
||
|
Рекурсия
|
|||
|---|---|---|---|
|
#18+
Как тогда правильно написать? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.01.2019, 11:35 |
|
||
|
Рекурсия
|
|||
|---|---|---|---|
|
#18+
Добрый день. Подскажите, пожалуйста, все-таки как скрипт нужно исправить, чтобы он заработал ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.04.2019, 06:58 |
|
||
|
Рекурсия
|
|||
|---|---|---|---|
|
#18+
*Ann*, а какая у вас СУБД - имя, версия? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.04.2019, 09:00 |
|
||
|
Рекурсия
|
|||
|---|---|---|---|
|
#18+
Пишу на Postgressql Если указать тип поля aolevel integer, то ошибка про несовпадение типов уже не выдается. Не уверена, что (tt.aolevel = 1)::integer правильно записано, но ошибки уже нет. Теперь выдается ошибка: function left(character varying, integer) does not exist для строки MAX( CASE WHEN lvl = 1 AND adr_adm_ter LIKE '[0-9][0-9][0-9][0-9][0-9][0-9],%' THEN LEFT( adr_adm_ter, 6 ) END ) as index, И ошибка "column "aolevel" does not exist" ругается на последний итоговый select. Сам запрос: WITH cte AS ( SELECT tt.id as base, (tt.aolevel = 1)::integer as lvl, tt.adr_adm_ter, tt.formalname FROM edw_prod.edw_ods.t_000148_ent_as_addrobj tt LEFT JOIN edw_prod.edw_ods.t_000148_ent_as_addrobj tt1 ON ( tt1.parent_id = tt.id ) WHERE tt1.parent_id IS NULL UNION ALL SELECT tt3.id as base, (tt3.aolevel + 1)::integer as lvl, tt.adr_adm_ter, tt.formalname FROM edw_prod.edw_ods.t_000148_ent_as_addrobj tt3 INNER JOIN edw_prod.edw_ods.t_000148_ent_as_addrobj tt ON ( tt.id = tt3.parent_id ) ) SELECT base, adr_adm_ter = MAX( CASE WHEN lvl = 1 THEN adr_adm_ter END ), MAX( CASE WHEN lvl = 1 AND adr_adm_ter LIKE '[0-9][0-9][0-9][0-9][0-9][0-9],%' THEN LEFT( adr_adm_ter, 6 ) END ) as index, MAX( CASE WHEN aolevel = 1 THEN formalname END ) as formalname1, MAX( CASE WHEN aolevel = 2 THEN formalname END ) as formalname2, MAX( CASE WHEN aolevel = 3 THEN formalname END ) as formalname3, MAX( CASE WHEN aolevel = 4 THEN formalname END ) as formalname4, MAX( CASE WHEN aolevel = 5 THEN formalname END ) as formalname5, MAX( CASE WHEN aolevel = 6 THEN formalname END ) as formalname6, MAX( CASE WHEN aolevel = 7 THEN formalname END ) as formalname7, MAX( CASE WHEN aolevel = 8 THEN formalname END ) as formalname8, MAX( CASE WHEN aolevel = 90 THEN formalname END ) as formalname90, MAX( CASE WHEN aolevel = 91 THEN formalname END ) as formalname91 FROM cte GROUP BY base limit 1000 ; ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.04.2019, 10:02 |
|
||
|
Рекурсия
|
|||
|---|---|---|---|
|
#18+
*Ann*Пишу на Postgressql Если указать тип поля aolevel integer, то ошибка про несовпадение типов уже не выдается. Не уверена, что (tt.aolevel = 1)::integer правильно записано, но ошибки уже нет. Теперь выдается ошибка: function left(character varying, integer) does not exist для строки MAX( CASE WHEN lvl = 1 AND adr_adm_ter LIKE '[0-9][0-9][0-9][0-9][0-9][0-9],%' THEN LEFT( adr_adm_ter, 6 ) END ) as index, И ошибка "column "aolevel" does not exist" ругается на последний итоговый select. Сам запрос: Код: sql 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. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. ;так нет у тебя в cte aolevel Есть lvl ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.04.2019, 10:06 |
|
||
|
Рекурсия
|
|||
|---|---|---|---|
|
#18+
*Ann* Код: sql 1. это ваще бредятина какая-то ... Это может "имелось в виду" ? Код: sql 1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.04.2019, 10:10 |
|
||
|
Рекурсия
|
|||
|---|---|---|---|
|
#18+
Согласна, бредятина )) Исправила. Вроде запрос заработал, но выдается какая-то ерунда... Взять для примера первую строку. В поле base выдается id улицы (433404, Ульяновская обл, Чердаклинский р-н, Богдашкино с., Полевая ул.), а в поле adr_adm_ter выдается адрес до населенного пункта "433404, Ульяновская обл, Чердаклинский р-н, Богдашкино с." и в итоге мне надо получить строку с такими значениями (если взять первую строку результатов из файла): formalname7 = Полевая formalname6 = Богдашкино formalname3 = Чердаклинский formalname1 = Ульяновская adr_adm_ter = 433404, Ульяновская обл, Чердаклинский р-н, Богдашкино с., Полевая ул. base = 24292037 Ошибка где-то в первых селектах. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.04.2019, 11:00 |
|
||
|
|

start [/forum/topic.php?fid=46&msg=39752942&tid=1688020]: |
0ms |
get settings: |
9ms |
get forum list: |
15ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
80ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
61ms |
get tp. blocked users: |
1ms |
| others: | 274ms |
| total: | 458ms |

| 0 / 0 |
