|
|
|
Поиск комбинаций строк в таблице
|
|||
|---|---|---|---|
|
#18+
Хочу посоветоваться в решении прикладной задачи. Свой вариант написал, работает точно и быстро, но есть ощущение, что можно сделать "красивее". Есть абстрактная система CRM, в ней список служб (продуктов) в иерархической форме. Код: 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. Есть список комбинаций продуктов. У меня ключом для комбинаций используются полные пути, так обеспечивается точность иерархии. Мой вариант происходит из excel-таблицы, составленной архитекторами и BA, возможно это повлияло на способ решения задачи. В принципе, список комбинаций может быть в любой форме, главное чтобы сохранились коды (имена) продуктов, их расположение в иерархии отосительно друг друга, была возможность добавлять дополнительные ключи (напр.: параметр продукта из другой таблицы, его состояние, и т.п.). Максимальное количество продуктов в комбинации ограничено и точно известно. В примере их четыре (далее будет понятно, почему это важно), но в реальности - их всего десять. Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. Комбинации могут частично пересекаться - MAP_1 и MAP_2 похожи, в MAP_2 на один продукт больше. В таких случаях при выборе используются параметры map_group и map_depth, выбирается максимальная "глубина" для совпадающей группы. Задача - найти в списке продуктов в рамках одного дерева точные комбинации в соответствии со списком, а также продукты, для которых комбинаций не нашлись. Прикладное применение - миграция из одной системы в другую, комбинации продуктов из старой системы превращаются в другие комбинации в новой, на основании таблиц, составленных бизнесом и архитекторами. Моё решение - совпадения проверять по строке пути и точному количеству строк. Делаю вспомогательную табличку: Код: plsql 1. 2. 3. Главный select. Немного громоздкий, но достаточно быстрый. Найденные комбинации разворачиваются в одну строку пивотом (отдельные столбцы для каждого продукта), и полученный результат фильтруется по map_group и map_depth. Код: 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. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. Если на вход подать сразу несколько миллионов строк, то он будет или тормозить или переполнит temp_segment. Как самостоятельный селект он используется только для проверки единичных вариантов. В боевом исполнении он встроен в parallel pipelined функцию, на вход получает от одного до сотни клиентов. С таким количеством справляется влёт. Но я продолжаю ломать голову - нет ли другого, более элегантного решения поиска заданных комбинаций в таблице? Может кто-то решал что-то подобное? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.05.2017, 12:13 |
|
||
|
Поиск комбинаций строк в таблице
|
|||
|---|---|---|---|
|
#18+
Никто? ;) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.05.2017, 11:13 |
|
||
|
Поиск комбинаций строк в таблице
|
|||
|---|---|---|---|
|
#18+
rpovarov, multiset? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.05.2017, 12:19 |
|
||
|
Поиск комбинаций строк в таблице
|
|||
|---|---|---|---|
|
#18+
rpovarovЗадача - найти в списке продуктов в рамках одного дерева точные комбинации в соответствии со списком, а также продукты, для которых комбинаций не нашлись. Код: plsql 1. ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.05.2017, 13:49 |
|
||
|
Поиск комбинаций строк в таблице
|
|||
|---|---|---|---|
|
#18+
dbms_photoshop Код: plsql 1. ? Так получается список вообще всего, полного совпадения и неполного. Нужно только полное совпадение комбинации, например для root_id = 1 не подходит MAP_2, так как отсуствует один из четырёх продуктов этой комбинации - '|ROOT1|PROD13'. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.05.2017, 15:21 |
|
||
|
Поиск комбинаций строк в таблице
|
|||
|---|---|---|---|
|
#18+
rpovarov, Цель найти root_id для каждого map, при этом root_id считается подходящим если его дети содержат все пути для конкретного map? Если для одного map подходит более одного root_id - какой берем? rpovarovУ меня ключом для комбинаций используются полные пути, так обеспечивается точность иерархии.Пути (составленные из prod_name) в твоей иерархии неуникальные, о каком ключе может быть речь? rpovarovПрикладное применение - миграция из одной системы в другую, комбинации продуктов из старой системы превращаются в другие комбинации в новой, на основании таблиц, составленных бизнесом и архитекторами.Так меняется иерархия или связи родитель-потомок остаются как есть, а меняются атрибуты сущности (пусть даже все атрибуты, включая имя)? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.05.2017, 19:15 |
|
||
|
Поиск комбинаций строк в таблице
|
|||
|---|---|---|---|
|
#18+
dbms_photoshopЦель найти root_id для каждого map, при этом root_id считается подходящим если его дети содержат все пути для конкретного map? Если для одного map подходит более одного root_id - какой берем? В обратном направлении - цель найти все map_id для дерева под одним root_id. В системе одна бизнес-служба (как её видит бизнес-аналитик) состоит из нескольких "технических" продуктов. К примеру, комбинация MAP_1 из трёх продуктов (ROOT1, PROD11 и PROD12) может быть интернет-тарифом, пусть будет INTERNET_STANDARD. А то же самое, но с ещё одним дополнительным PROD13, даёт комбинацию MAP_2, которая для бизнес-аналитика - интернет с телевидением, пусть будет INTERNET_IPTV. Бизнес придумал обновить CRM и всё это перенести в новую систему. Там всё по другому, миграции один к одному не получится. Поэтому миграция будет проходить на уровне бизнес-служб, которые в новой системе уже сами развернутся как надо, по своим правилам. И вот бизнес-аналитики с другими специалистами по продуктам составляют огромную Excel таблицу, в которой перечислены все существующие в старой системе комбинации продуктов и как они складываются в службы. Из такой таблицы после обработки в результате получится prod_map. Задача - получить список MAP_1, MAP_2, ... MAP_N для каждого отдельного подписчика (будем считать, что один клиент имеет всего одно дерево продуктов, тогда root_id - это ключ, который однозначно идентифицирует клиента). Должно быть полное совпадение списка продуктов из конфигурации MAP_x, например, если есть |ROOT1 и |ROOT1|PROD12, но нет |ROOT1|PROD11, то нет и совпадения. Продукты, для которых не нашлась комбинация, надо найти и показать бизнес-аналитикам, чтобы они решили, что с ними делать. Как вариант, чтобы выпустили новую обновлённую версию prod_map. Т.е. на входе у нас prods, а на выходе получаем список MAP_x и информацию о тех продуктах, для которых MAP_x не нашлись. Не должно остаться ни одного забытого продукта. dbms_photoshopПути (составленные из prod_name) в твоей иерархии неуникальные, о каком ключе может быть речь? Ключ, наверное, не совсем правильное слово. Путь - это идентификатор, показывающий однозначное иерархическое подчинение продукта. Потому что один и тот же продукт с кодом PROD11 может находится как под ROOT1, и тогда это будет одна служба, так и под ROOT2 или ROOT3, и тогда это будет совсем другая служба и другой тариф. А вот комбинация путей (набор строчек под единым MAP_x) должна быть уникальная. dbms_photoshopТак меняется иерархия или связи родитель-потомок остаются как есть, а меняются атрибуты сущности (пусть даже все атрибуты, включая имя)? Меняется вообще всё. Из старой системы надо вытащить данные и поднять их на бизнес-уровень, как список служб (т.е. map_id). Который на следующем шаге превратится в исходные данные для создания этих служб в новой системе. Или в репорт качества данных, или ещё во что-нибудь... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.05.2017, 21:32 |
|
||
|
Поиск комбинаций строк в таблице
|
|||
|---|---|---|---|
|
#18+
rpovarovВ обратном направлении - цель найти все map_id для дерева под одним root_id.+ отсутствующие продукты из маппинга. Код: 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.05.2017, 05:31 |
|
||
|
Поиск комбинаций строк в таблице
|
|||
|---|---|---|---|
|
#18+
rpovarov, Учись формулировать проще и без лишней шелухи. В твоем сообщении 8 раз встречается слово "бизнес". :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.05.2017, 05:34 |
|
||
|
Поиск комбинаций строк в таблице
|
|||
|---|---|---|---|
|
#18+
dbms_photoshoprpovarov, Учись формулировать проще и без лишней шелухи. В твоем сообщении 8 раз встречается слово "бизнес". :) Это локальный сленг, мы так называем внешнюю стихийную силу, раздающую нам указания ;) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.05.2017, 06:43 |
|
||
|
Поиск комбинаций строк в таблице
|
|||
|---|---|---|---|
|
#18+
dbms_photoshop+ отсутствующие продукты из маппинга. Код: plsql 1. 2. 3. 4. 5. 6. В этом варианте отсутствующие продукты относительно одной конкретной комбинации, а нужно относительно всех найденных. В варианте root_id = 10 бесхозным остался только продукт 42, потому что 31 используется в MAP_2, 41 в MAP_3 и т.д. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.05.2017, 10:21 |
|
||
|
Поиск комбинаций строк в таблице
|
|||
|---|---|---|---|
|
#18+
rpovarovdbms_photoshop+ отсутствующие продукты из маппинга. Код: plsql 1. 2. 3. 4. 5. 6. В этом варианте отсутствующие продукты относительно одной конкретной комбинации, а нужно относительно всех найденных. В варианте root_id = 10 бесхозным остался только продукт 42, потому что 31 используется в MAP_2, 41 в MAP_3 и т.д. Объяснять это явно не твой конек. Если бы в голове была ясная картина, то и объяснить было бы просто и запрос написать. Код: 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. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.05.2017, 11:53 |
|
||
|
Поиск комбинаций строк в таблице
|
|||
|---|---|---|---|
|
#18+
dbms_photoshopОбъяснять это явно не твой конек. Если бы в голове была ясная картина, то и объяснить было бы просто и запрос написать. Может и так. Мне казалось, что в самом первом сообщении написал понятно, плюс ещё исходники. Комбинации могут частично пересекаться - MAP_1 и MAP_2 похожи, в MAP_2 на один продукт больше. В таких случаях при выборе используются параметры map_group и map_depth, выбирается максимальная "глубина" для совпадающей группы. Задача - найти в списке продуктов в рамках одного дерева точные комбинации в соответствии со списком, а также продукты, для которых комбинаций не нашлись. В любом случае твой вариант интереснее и чище. Спасибо! Вот он же с пивотом и фильтрацией по map_depth. Код: 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. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. Я его ещё проверю на боевой конфигурации, потом поделюсь впечатлениями. И за "outer join partition by" отдельное спасибо, этот вариант джойна вообще прошёл мимо меня, пойду читать документацию. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.05.2017, 14:46 |
|
||
|
Поиск комбинаций строк в таблице
|
|||
|---|---|---|---|
|
#18+
Усложняем. Вылез вариант, когда может быть параллельно несколько одинаковых ветвей под одним корнем. Код: 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. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. На выходе, соответственно, должны получиться три ветви с map_id = MAP4 (и продукты 8 и 9 как unmapped). Уже всю голову сломал, как от себя отделить эти ветви. Если получится размножить корневой продукт отдельно к каждой ветви, повесить на всю ветвь какой-нибудь id, то потом этот id можно прописать в "... over(partition by..." рядом с root_id, и всё должно сработать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.05.2017, 18:20 |
|
||
|
Поиск комбинаций строк в таблице
|
|||
|---|---|---|---|
|
#18+
rpovarovУже всю голову сломал, как от себя отделить эти ветви. Если получится размножить корневой продукт отдельно к каждой ветви, повесить на всю ветвь какой-нибудь id, то потом этот id можно прописать в "... over(partition by..." рядом с root_id, и всё должно сработать.Ну ты был близок. А в чем проблема размножить? Либо self join по like (как в примере ниже) либо строить дерево сначала от корня, а потом к корню. Идея та же, только использовано размноженное дерево вместо оригинального (super_tree instead of product_tree) и добавлен leaf_id в логику. Код: 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. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.05.2017, 20:17 |
|
||
|
Поиск комбинаций строк в таблице
|
|||
|---|---|---|---|
|
#18+
dbms_photoshopНу ты был близок. А в чем проблема размножить? Либо self join по like (как в примере ниже) либо строить дерево сначала от корня, а потом к корню. Проблема, как всегда, в ДНК :) Я раньше подобные задачи решал нахрапом черед PL/SQL, но практика показала, что чем больше запихнуть в SQL (в разумных пределах), тем лучше и быстрее в результате всё работает. Но мозги перестраивать силком надо... Спасибо за пример! Завтра погоняю на работе, может ещё что найду интересного. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.05.2017, 20:30 |
|
||
|
Поиск комбинаций строк в таблице
|
|||
|---|---|---|---|
|
#18+
rpovarovdbms_photoshopНу ты был близок. А в чем проблема размножить? Либо self join по like (как в примере ниже) либо строить дерево сначала от корня, а потом к корню. Проблема, как всегда, в ДНК :) Я раньше подобные задачи решал нахрапом черед PL/SQL, но практика показала, что чем больше запихнуть в SQL (в разумных пределах), тем лучше и быстрее в результате всё работает. Но мозги перестраивать силком надо... Спасибо за пример! Завтра погоняю на работе, может ещё что найду интересного.Это хорошо, что ты перестал заниматься глупостями. Я закончил свое исследование разумных пределов SQL vs PL/SQL, надеюсь до конца недели выложить. :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.05.2017, 20:38 |
|
||
|
Поиск комбинаций строк в таблице
|
|||
|---|---|---|---|
|
#18+
dbms_photoshopЭто хорошо, что ты перестал заниматься глупостями. Я закончил свое исследование разумных пределов SQL vs PL/SQL, надеюсь до конца недели выложить. :) Была одна задачка, которая чистым SQL не решалась совсем или решалась с огромным геморроем и ограничениями. Тоже обход дерева, но нет прямой иерархии, она строится на ходу в зависимости от того, что нашлось в каждой ветке. Конфигурация была написана для Java-кода в бэкенде, и он там успешно работает. Потребовалось его повторить, но прямо над базой данных. Обход дерева рекурсией в PL/SQL, но там, где ситуация позволяет, скармливаю таблицы в SQL. В результате довольно быстро работает (если распараллелить), и побочным эффектом вывод в логи или на экран всего построенного дерева с комментариями :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.05.2017, 20:53 |
|
||
|
Поиск комбинаций строк в таблице
|
|||
|---|---|---|---|
|
#18+
rpovarovБыла одна задачка, которая чистым SQL не решалась совсем или решалась с огромным геморроем и ограничениями. Тоже обход дерева, но нет прямой иерархии, она строится на ходу в зависимости от того, что нашлось в каждой ветке. Конфигурация была написана для Java-кода в бэкенде, и он там успешно работает. Потребовалось его повторить, но прямо над базой данных. Обход дерева рекурсией в PL/SQL, но там, где ситуация позволяет, скармливаю таблицы в SQL. В результате довольно быстро работает (если распараллелить), и побочным эффектом вывод в логи или на экран всего построенного дерева с комментариями :)Описывая свой "любимый говнокод" своими же ощущениями наивно полагать встретить понимание. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.05.2017, 21:06 |
|
||
|
Поиск комбинаций строк в таблице
|
|||
|---|---|---|---|
|
#18+
rpovarovнет прямой иерархии, она строится на ходу в зависимости от того, что нашлось в каждой веткеЭто наводит на мысль, что на SQL было бы уместнее решать с помощью rec with чем connect by. А я имею в виду, что есть случаи, когда PL/SQL предпочтительнее базового SQL без ухищрений. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.05.2017, 22:40 |
|
||
|
Поиск комбинаций строк в таблице
|
|||
|---|---|---|---|
|
#18+
dbms_photoshopИдея та же, только использовано размноженное дерево вместо оригинального (super_tree instead of product_tree) и добавлен leaf_id в логику. Если в дереве и prod_map попадается комбинация, где несколько последних в цепочке продуктов на одном уровне Код: plaintext 1. 2. 3. но при этом нет параллельных ветвей, то получается интересно :) Код: plaintext 1. 2. 3. 4. 5. 6. 7. Два "хвоста" образовали каждый свою ветку по leaf_id. При этом, если присутствуют параллельные ветки, то всё в порядке Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. Немного поправил product_tree и super_tree, размножаю только множественные случаи Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. Результат Код: plaintext 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. 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. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.05.2017, 15:00 |
|
||
|
Поиск комбинаций строк в таблице
|
|||
|---|---|---|---|
|
#18+
rpovarovДва "хвоста" образовали каждый свою ветку по leaf_id. При этом, если присутствуют параллельные ветки, то всё в порядке Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. Откуда тут взялось 8 строк вместо шести?? Выше в примере два листа грубины три. 3*2=6. rpovarovНемного поправил product_tree и super_tree, размножаю только множественные случаиКакое отношение этот фикс имеет к реальной жизни? Или, говоря твоим сленгом, какое бизнес правило говорит, что надо "размножать только множественные"? Больше похоже либо на костыль либо для кривых данных либо от недопонимания принципа работы. Это как некоторые разработчики которые не хотят вникать до конца почему запрос возвращает дубли просто засовывают в него distinct и не парятся. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.05.2017, 15:24 |
|
||
|
Поиск комбинаций строк в таблице
|
|||
|---|---|---|---|
|
#18+
dbms_photoshop, Этих строчек не было в исходном примере. Я проверял скрипт на боевых таблицах, и нашёл комбинацию, при которой вылезает косяк. Оформил это в виде нового примера и запостил вместе со своим костылём. То, что в старой системе было в одном экземпляре, в новой тоже будет в одном. Например, тариф. Если было несколько одинаковых веток, то и в новой тоже будет столько же. Например, несколько сим-карт к одному тарифу. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.05.2017, 16:23 |
|
||
|
Поиск комбинаций строк в таблице
|
|||
|---|---|---|---|
|
#18+
rpovarovdbms_photoshop, Этих строчек не было в исходном примере. Я проверял скрипт на боевых таблицах, и нашёл комбинацию, при которой вылезает косяк. Оформил это в виде нового примера и запостил вместе со своим костылём. То, что в старой системе было в одном экземпляре, в новой тоже будет в одном. Например, тариф. Если было несколько одинаковых веток, то и в новой тоже будет столько же. Например, несколько сим-карт к одному тарифу.Я не говорил про исходный пример. Я ссылался на последнее сообщение. Еще раз, откуда у тебя взялось 8 вместо 6. Код: 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. Касательно костылей, нормальный подход как раз отличается от костыля тем, что данные приводятся в нужную форму до применения логики. А говнокод - это когда начинает что-то вылазить неожиданное и не учтенное во входных данных, а разработчик пытается от этого избавиться в процессе. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.05.2017, 16:39 |
|
||
|
Поиск комбинаций строк в таблице
|
|||
|---|---|---|---|
|
#18+
dbms_photoshop, В сообщении 20521106 , где начали решать проблему одинаковых ветвей, пример был упрощённый, из трёх продуктов. Моя ошибка. Если бы взял конфигурацию для четырёх продуктов из самого первого сообщения - было бы правильнее. "Хорошая мысля приходит опосля..." ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.05.2017, 16:52 |
|
||
|
Поиск комбинаций строк в таблице
|
|||
|---|---|---|---|
|
#18+
rpovarov, Было бы намного понятнее, если бы ты в моем последнем запросе просто подставил данные на которых он возвращает не то, что ты ожидаешь. Мне не совсем понятно что не так, хотя если твое решение тебя вполне устраивает, на этом можно и зарешить. По числу отвечающих в этой ветке ты можешь сделать определенные выводы про умение просто подавать информацию и доступно объяснять. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.05.2017, 17:31 |
|
||
|
Поиск комбинаций строк в таблице
|
|||
|---|---|---|---|
|
#18+
dbms_photoshopБыло бы намного понятнее, если бы ты в моем последнем запросе просто подставил данные на которых он возвращает не то, что ты ожидаешь. Мне не совсем понятно что не так, хотя если твое решение тебя вполне устраивает, на этом можно и зарешить. Прошу прощения, что не сразу отвечаю. Не успеваю иногда. Пытался разобраться, почему у меня на, казалось бы, одинаковых данных выходят разные результаты. Подготовлю входные данные, которые должны будут покрыть все спорные варианты, и вернусь. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.05.2017, 11:03 |
|
||
|
Поиск комбинаций строк в таблице
|
|||
|---|---|---|---|
|
#18+
Возвращаюсь с новым решением. Основной проблемой было то, что при нескольких экземплярах одного и того же продукта нужно отделить эти экземпляры уникальным ключом так, чтобы в эту выделенную ветку попали также корневой продукт и остальные одиночные продукты (это важно для дальнейшего "опознания" комбинаций). Решил разделить super_tree из предыдущих попыток на два отдельных шага. В результате получается так: 1. Первый проход по дереву, строим product_path и unique_path, считаем количество повторений product_path. 2. Проход по результату из п.1 рекурсивным селектом, ищем повторяющиеся ветки. Как только наткнулись - вешаем на ветку идентификатор branch_id, и обозначаем им все остальные продукты ниже в этой ветке. Теоретически ниже может быть ещё одно разветвление с повтором (в реальных данных такого не встречается), оно игнорируется. 3. Для всех повторяющихся веток размножаем корневые и неповторяющиеся продукты. Наверняка можно совместить шаг 1 и 2 в один, но я пока не придумал как. Исходная таблица Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. После применения super_tree Код: 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. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.06.2017, 11:48 |
|
||
|
Поиск комбинаций строк в таблице
|
|||
|---|---|---|---|
|
#18+
rpovarov, А какую задачу ты сейчас решаешь? Получить для каждого листа всех его родителей? Тогда можно взять мой запрос тут 20524387 и добавить в него выделенное. Код: 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. 32. 33. 34. 35. 36. 37. 38. Семь листьев глубины три и один глубины два итого 7*3+1*2=23 строки. Это ожидается? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.06.2017, 01:44 |
|
||
|
Поиск комбинаций строк в таблице
|
|||
|---|---|---|---|
|
#18+
dbms_photoshoprpovarov, А какую задачу ты сейчас решаешь? Получить для каждого листа всех его родителей? ... Тогда можно взять мой запрос тут 20524387 и добавить в него выделенное. Семь листьев глубины три и один глубины два итого 7*3+1*2=23 строки. Это ожидается? Если идти от листьев, то каждый лист генерирует свою собственную ветку, это неправильно. В последнем примере продукты PROD121 и PROD122 оба являются листьями и находятся в одной ветке на одинаковом уровне под общим родителем PROD12. Они так и должны остаться вместе в одной ветке. Т.е. должно получиться не две: Код: plaintext 1. 2. 3. 4. 5. 6. а одна: Код: plaintext 1. 2. 3. 4. В примере три экземпляра продукта PROD12, они ближе всего к корню, значит с них и начинаем делить. В результате должно получиться три полные ветви для каждого из PROD12, и одна "дефолтная" для остальных продуктов, не попадающих в те три ветви. Вот ещё один боевой пример прямо из базы (привязок нет, NDA не нарушается), в нём куча "листьев" Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. Если его подставить в твой пример, то листья сгенерируют 10+ веток, а их на самом деле всего три (две для продуктов OP0801, и одна общая). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.06.2017, 11:26 |
|
||
|
Поиск комбинаций строк в таблице
|
|||
|---|---|---|---|
|
#18+
rpovarovВ примереВроде мой последний запрос возвращает то же количество строк, что и твой последний. Можно, конечно, допилить с учетом новых хотелок, но есть подозрение, что ты уже пытаешься реализовать то, что делать не надо. В конце концов, тебе виднее, что за логику надо реализовать. Если будут конкретные вопросы - спрашивай. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.06.2017, 11:53 |
|
||
|
Поиск комбинаций строк в таблице
|
|||
|---|---|---|---|
|
#18+
dbms_photoshopВроде мой последний запрос возвращает то же количество строк, что и твой последний. Если подставить "боевой", то количество строк разное, в твоём больше (48 против 28). Но количество строк в принципе не так важно, основная проблема в том, что ветки разбиваются и потом не совпадают с map-таблицей. dbms_photoshopМожно, конечно, допилить с учетом новых хотелок, но есть подозрение, что ты уже пытаешься реализовать то, что делать не надо. В конце концов, тебе виднее, что за логику надо реализовать. Если будут конкретные вопросы - спрашивай. Последняя версия кода вроде делает всё что нужно. По крайней мере, пока ещё не наткнулся на вариант, где она лажает. Благодаря твоим вариантам и моим попыткам их доработать нашлись и были исправлены другие местные косяки в данных и map-таблицах :) Вопрос, собственно, такой - можно ли как-то совместить эти две конструкции в одну (и есть ли в этом смысл с точки зрения оптимизации)? В первой считаются пути и их количество для выявления нескольких экземпляров одного продукта, во второй на основании этого количества генерируется параметр branch. Код: 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. И ещё один вопрос, который тут не обсуждался, но связан с темой. В части, выделенной красным цветом - я правильно надеюсь на short-circuit evaluation, и при выполнении условия pm.param_key is null Оракл не пойдёт дальше и не будет выполнять селект из второго условия? Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.06.2017, 12:28 |
|
||
|
Поиск комбинаций строк в таблице
|
|||
|---|---|---|---|
|
#18+
rpovarovВопрос, собственно, такой - можно ли как-то совместить эти две конструкции в однуОтвет: rec with там вообще не нужен. rpovarovЕсли идти от листьев, то каждый лист генерирует свою собственную ветку, это неправильно. В последнем примере продукты PROD121 и PROD122 оба являются листьями и находятся в одной ветке на одинаковом уровне под общим родителем PROD12. Они так и должны остаться вместе в одной ветке.Что значит на одной "ветке"? Имеется в виду пути до листьев полностью совпадают? Ну так это поведение по умолчанию connect by выведет всех родителей по разу и каждый лист по разу и ты получаешь. rpovarov Код: plaintext 1. 2. 3. 4. Когда ты это ясно сможешь для себя сформулировать, тогда и запрос сам собой напишется. rpovarovВопрос, собственно, такой - можно ли как-то совместить эти две конструкции в однуЛюбители абсолютной строгости рекомендуют прибегать к case. 20384658 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.06.2017, 13:07 |
|
||
|
Поиск комбинаций строк в таблице
|
|||
|---|---|---|---|
|
#18+
В последней цитате должен быть второй вопрос. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.06.2017, 13:16 |
|
||
|
Поиск комбинаций строк в таблице
|
|||
|---|---|---|---|
|
#18+
dbms_photoshopНепонятно уже надо тебе что-то размножать или нет и если надо, то при каких условиях. Когда ты это ясно сможешь для себя сформулировать, тогда и запрос сам собой напишется. Ну я же привёл рабочий пример в 20563070 . Этот код делает сейчас именно то, что нужно. В случае нескольких экземпляров одного и того же продукта генерируются полные ветки для них и обозначаются идентификатором branch_id. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.06.2017, 13:22 |
|
||
|
Поиск комбинаций строк в таблице
|
|||
|---|---|---|---|
|
#18+
rpovarov, Ммм... то, что делает твой запрос понятно только тебе. Хотя, подозреваю, если ты посмотришь на него через год и тебе будет вообще непонятно что это за 'x' и что курил аффтар. Код: plaintext 1. 2. Код: plaintext 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. Зачем продукт с ид 7 и 8 продублированы по 4 раза? Почему продукт с ид 1 тоже продублирован именно 4 раза? Почему ветку "идентифицируют" два айдишника независимо от глубины. и т. д. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.06.2017, 14:12 |
|
||
|
Поиск комбинаций строк в таблице
|
|||
|---|---|---|---|
|
#18+
dbms_photoshop, Если отсортировать по другому, то так понятнее. Код: plaintext Продукты 8 (PROD2) и 9 (PROD22) не принадлежали веткам с multi-instance продуктами, но они могут быть важны для идентификации службы. Например, если служба описана как комбинация продуктов ROOT1, PROD12, PROD121, PROD122, PROD2, то, не включив PROD2, я теряю всю службу. Дупликаты продуктов не мешают, они отфильтровываются на конечном этапе. Ветка идентифицируется через unique_path продукта с multi-instance, ближайшего к корню. В примере это PROD12, он на втором уровне, поэтому branch_id состоит из двух элементов. Если разветвление будет на третьем уровне, то branch_id будет из трёх элементов ("боевой" пример как раз такой). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.06.2017, 14:39 |
|
||
|
Поиск комбинаций строк в таблице
|
|||
|---|---|---|---|
|
#18+
dbms_photoshopХотя, подозреваю, если ты посмотришь на него через год и тебе будет вообще непонятно что это за 'x' и что курил аффтар. Борюсь с этим явлением щедро рассыпая комментарии и пояснения в коде :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.06.2017, 14:42 |
|
||
|
Поиск комбинаций строк в таблице
|
|||
|---|---|---|---|
|
#18+
rpovarov, У тебя логика завязана на второй уровень и не надо создавать иллюзии, что размножение будет корректным при любой ветвистости и дубликатных путях. Учитывая сказанное "размножение" опять таки достигается путем self join только условие соединения более замысловатое. Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. Код: plaintext 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. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.06.2017, 17:20 |
|
||
|
Поиск комбинаций строк в таблице
|
|||
|---|---|---|---|
|
#18+
dbms_photoshoprpovarov, У тебя логика завязана на второй уровень и не надо создавать иллюзии, что размножение будет корректным при любой ветвистости и дубликатных путях. У меня как раз уровень вычисляется динамически, берётся первый, где нашлись дубликаты. Для этого и делался второй проход with rec. Например, вот ветвление на третьем (|PR0103|OP0807|OP0801): Код: 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. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. Код: plaintext Можно даже оба набора исходных данных (со вторым и третьим уровнем) слить воедино, и скрипт правильно отработает: Код: 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. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.06.2017, 17:41 |
|
||
|
|

start [/forum/topic.php?all=1&fid=52&tid=1885749]: |
0ms |
get settings: |
7ms |
get forum list: |
11ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
158ms |
get topic data: |
6ms |
get forum data: |
2ms |
get page messages: |
40ms |
get tp. blocked users: |
1ms |
| others: | 241ms |
| total: | 470ms |

| 0 / 0 |
