|
|
|
Помогите составить историческую таблицу
|
|||
|---|---|---|---|
|
#18+
Помогите довести до ума запрос. У меня есть лог, в котором фиксируется изменение данных. Нужные данные из лога я получаю таким запросом: Код: plsql 1. 2. 3. 4. CUSTOMER_IDOLD_VALUENEW_VALUEMOMENT7853113425530.12.2016 15:26:437853125533430.12.2016 15:26:517853133421430.12.2016 15:27:04785312145530.12.2016 15:29:31785315513430.12.2016 15:29:36 Из этой таблицы мне нужно составить историческую таблицу в стиле id, from_date, to_date. Я делаю так: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. CUSTOMER_IDOLD_VALUENEW_VALUEMOMENTGROUP_IDDATE_BEGDATE_END7853113425530.12.2016 15:26:4325530.12.2016 15:26:4330.12.2016 15:26:517853125533430.12.2016 15:26:5133430.12.2016 15:26:5130.12.2016 15:27:047853133421430.12.2016 15:27:0421430.12.2016 15:27:0430.12.2016 15:29:31785312145530.12.2016 15:29:315530.12.2016 15:29:3130.12.2016 15:29:36785315513430.12.2016 15:29:3613430.12.2016 15:29:36 Почти все хорошо, но мне нужно также получить самую первую запись с group_id, которая действует с c.CREATE_DATE до 30.12.2016 15:26:43, то есть должно получиться CUSTOMER_IDOLD_VALUENEW_VALUEMOMENTGROUP_IDDATE_BEGDATE_END7853113418.11.2016 15:49:0530.12.2016 15:26:437853113425530.12.2016 15:26:4325530.12.2016 15:26:4330.12.2016 15:26:517853125533430.12.2016 15:26:5133430.12.2016 15:26:5130.12.2016 15:27:047853133421430.12.2016 15:27:0421430.12.2016 15:27:0430.12.2016 15:29:31785312145530.12.2016 15:29:315530.12.2016 15:29:3130.12.2016 15:29:36785315513430.12.2016 15:29:3613430.12.2016 15:29:36 Что-то не соображу, как лучше всего сделать "раздвоение" строк для первой записи. "Раздвоение" в самом начале видимо является неверным: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. поскольку я не могу получить нужное значение GROUP_ID. И кроме того, таблица BM_ACTION_LOG довольно объемная и подобные манипуляции сильно сажают производительность запроса. ________________________ Мы смотрим с оптимизмом... ...в оптический прицел. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.02.2017, 18:16 |
|
||
|
Помогите составить историческую таблицу
|
|||
|---|---|---|---|
|
#18+
Alibek B., мож моделькой прономеровать с 1 для індекса 0 новая строка напр Код: 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. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.02.2017, 19:26 |
|
||
|
Помогите составить историческую таблицу
|
|||
|---|---|---|---|
|
#18+
Alibek B."раздвоение" строк для первой записи Код: plaintext 1. Для 12с более эффективно решалось бы через pattern matching. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.02.2017, 19:54 |
|
||
|
Помогите составить историческую таблицу
|
|||
|---|---|---|---|
|
#18+
dbms_photoshopAlibek B."раздвоение" строк для первой записи Код: plaintext 1. Для 12с более эффективно решалось бы через pattern matching. в 11-ке вроде тож прокатіт Код: plsql 1. 2. 3. 4. 5. 6. 7. или имелось ввиду что-то другое? ..... stax ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.02.2017, 21:40 |
|
||
|
Помогите составить историческую таблицу
|
|||
|---|---|---|---|
|
#18+
stax.. , точно, про модель я не подумал. Спасибо, самое то. dbms_photoshop , да, дублировать строку надо было на row_number=1. Но вариант с моделью мне нравится больше. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.02.2017, 22:18 |
|
||
|
Помогите составить историческую таблицу
|
|||
|---|---|---|---|
|
#18+
Составил такой запрос: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. CUSTOMER_IDVERSIONGROUP_IDDATE_BEGDATE_END78531013430.12.2016 15:26:4378531125530.12.2016 15:26:4330.12.2016 15:26:5178531233430.12.2016 15:26:5130.12.2016 15:27:0478531321430.12.2016 15:27:0430.12.2016 15:29:317853145530.12.2016 15:29:3130.12.2016 15:29:3678531513430.12.2016 15:29:36 Работает весьма шустро, даже быстрее, чем я рассчитывал (около 150мс, при этом в таблице порядка 5кк записей). Единственное хотел бы уточнить — не следует ли сразу обработать null-значения для дат (nvl(DATE_BEG,DATE'1000-01-01') as DATE_BEG, nvl(DATE_END,DATE'9999-01-01') as DATE_END), чтобы в последующих соединениях не использовать nvl, или нет особой разницы? То есть: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. или Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.02.2017, 23:05 |
|
||
|
Помогите составить историческую таблицу
|
|||
|---|---|---|---|
|
#18+
Посоветуйте еще с одним моментом. Есть таблица CUSTOMERS, в которой есть поля CUSTOMER_ID и GROUP_ID. Историю изменений GROUP_ID я могу получить из журнала, но это не совсем достоверная информация — в некоторых случаях изменение группы не фиксируется в журнале, кроме того в журнале не всегда фиксируется номер группы при создании записи в таблице CUSTOMERS. Кроме того, история изменений существенна только в случае определенной группы (группа "Корзина", куда "удаляются" записи), в остальных случаях (когда запись не "удалена") можно использовать текущую группу. Если такое решать «в лоб», то получается примерно такой запрос: Код: 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. А можно ли в случае CUSTOMERS.GROUP_ID=54 вообще не делать джойны с подзапросом? Для этого можно в модели добавить условие «and CUSTOMER_ID in (select CUSTOMER_ID from CUSTOMERS where GROUP_ID=54)». Это нормальный способ или есть что-то более правильное? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.02.2017, 10:10 |
|
||
|
Помогите составить историческую таблицу
|
|||
|---|---|---|---|
|
#18+
Не осилил я модель, чтобы составить ее в одном запросе (без подзапросов). Воспользовался советом dbms_photoshop , там для меня проще. Составил такой запрос: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. Смысл запроса в следующем: если для записи найдена достоверная история в журнале операций, то в ODCINumberList возвращается массив из двух элементов, для первой записи в журнале, чтобы ее раздвоить, и массив из одного элемента для остальных записей в журнале. Если же достоверных данных в журнале не найдено, то возвращается пустой массив. Затем делается left join с этим массивом, для первой записи из журнала строка должна раздвоиться, для остальных случаев строка остается (так как left join). Однако при выполнении этого запроса я получаю пустой результат. Если же left join я комментирую, то получаю результат из одной строки. Не могу понять, куда пропадает строка. Или это особенности TABLE? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.02.2017, 17:33 |
|
||
|
Помогите составить историческую таблицу
|
|||
|---|---|---|---|
|
#18+
Кстати, если сделать так: Код: plsql 1. 2. 3. 4. то строка не пропадает и запрос работает, как я хочу. Нашел такую тему: http://www.sql.ru/forum/777843/ocherednoy-bag-s-left-join Прочитал, но не совсем понял, баг это или особенности table(). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.02.2017, 17:36 |
|
||
|
Помогите составить историческую таблицу
|
|||
|---|---|---|---|
|
#18+
Alibek B.Прочитал, но не совсем понял, баг это или особенности table().В коллекциях для этой задачи нет особой необходимости, то было больше для баловства (если интересны детали - прочитай "unnesting collections" в pdf здесь: 20168262 ). Можешь соединяться с (... union all ...). stax..или имелось ввиду что-то другое?Имелось в виду, что если имеется 12с, то строку можно добавить с помощью pattern matching. Правда, подозреваю, это можно сделать только если больше одной строки на customer_id. Так что не очень решение. Нет 12с под рукой, чтоб попробовать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.02.2017, 18:09 |
|
||
|
Помогите составить историческую таблицу
|
|||
|---|---|---|---|
|
#18+
dbms_photoshop, я етот pattern matching не совсем понял, да и практики у меня сейчас нет ищу работу ..... stax ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.02.2017, 21:27 |
|
||
|
Помогите составить историческую таблицу
|
|||
|---|---|---|---|
|
#18+
dbms_photoshopто было больше для баловства Видимо да, для больших объемов это не подходит. Если у меня запрос с моделью выполнялся 160мс, то запрос с коллекциями выполнялся более 8 минут. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.02.2017, 21:51 |
|
||
|
Помогите составить историческую таблицу
|
|||
|---|---|---|---|
|
#18+
dbms_photoshopstax..или имелось ввиду что-то другое?Имелось в виду, что если имеется 12с, то строку можно добавить с помощью pattern matching. Правда, подозреваю, это можно сделать только если больше одной строки на customer_id. Так что не очень решение. Нет 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. Alibek B.dbms_photoshopто было больше для баловства Видимо да, для больших объемов это не подходит. Если у меня запрос с моделью выполнялся 160мс, то запрос с коллекциями выполнялся более 8 минут.Да, объемы прямо огромные, если модель выполняется за 160мс. Ну ты же, я надеюсь в состоянии посмотреть план и куда уходит время. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.02.2017, 22:49 |
|
||
|
Помогите составить историческую таблицу
|
|||
|---|---|---|---|
|
#18+
stax..dbms_photoshop, я етот pattern matching не совсем понял, да и практики у меня сейчас нет ищу работу ..... staxМне кажется я достаточно понятно рассказываю про него тут - The Power of Oracle SQL . ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.02.2017, 22:50 |
|
||
|
Помогите составить историческую таблицу
|
|||
|---|---|---|---|
|
#18+
dbms_photoshopДа, объемы прямо огромные, если модель выполняется за 160мс. Планы и трассировку я не смотрел, но мне чисто умозрительно кажется, что запрос с подзапросом, где внутри с помощью decode составляется коллекция, а снаружи по этой коллекции строится таблица, не может быть быстрым. Такой вариант, кстати, гораздо проще и понятнее: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. и выполняется быстрее: при первом запуске около 15с, при последующих менее 300мс. Но тем не менее, для данной задачи мне самым оптимальным кажется использование модели. Буду изучать документацию и примеры и делать через нее. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2017, 09:05 |
|
||
|
Помогите составить историческую таблицу
|
|||
|---|---|---|---|
|
#18+
Alibek B.трассировку я не смотрелА её и не надо смотреть. Для анализа производительности в 99% случаев достаточно dbms_xplan.display_cursor с включенными runtime execution statistics или dbms_sqltune.report_sql_monitor. Alibek B.мне чисто умозрительно кажетсяAlibek B.мне самым оптимальным кажетсяПонятно. Дальнейший диалог смысла не имеет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2017, 12:20 |
|
||
|
Помогите составить историческую таблицу
|
|||
|---|---|---|---|
|
#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. 44. 45. 46. 47. 48. 49. 50. 51. 1. Информация из журнала операций используется только для некоторых групп, для остальных групп всегда используется текущее значение группы. 2. Если для записи нет данных в журнале операций, то чтобы избежать добавления новой строки с индексом 0 в модели, в dimension я использую nvl2; для таких строк индекс всегда равен нулю, для остальных случаев он начинается с 1. 3. Поскольку при отсутствии данных в журнале операций элементов с индексами от 1 не существует, в rules также приходится использовать nvl. Вообщем все работает, но мне не нравится обилие nvl. Видимо из-за этого запрос выполняется около минуты. Не посоветуете, можно ли его ускорить? Нынешний план выглядит следующим образом: Код: 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. 27. 28. 29. 30. 31. 32. 33. 34. 35. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2017, 12:38 |
|
||
|
Помогите составить историческую таблицу
|
|||
|---|---|---|---|
|
#18+
Подскажите, как в модели ссылаться на текущее и предыдущее значение? У меня есть модель со следующими правилами: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. Теперь нужно добавить в модель еще одно поле LAST_ID, которое заполняется по следующему правилу: 1. Если текущий GROUP_ID in (1,2,3), то LAST_ID(i)=LAST_ID(i-1) 2. В ином случае LAST_ID(i)=GROUP_ID(i) Как мне записать это правило? Я пробовал так: Код: plsql 1. 2. но получаю ошибку "ORA-32622: недопустимая ссылка на несколько ячеек". ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.02.2017, 18:25 |
|
||
|
Помогите составить историческую таблицу
|
|||
|---|---|---|---|
|
#18+
Разобрался, справа нужно было использовать функцию CV(). По правде говоря с непривычки понять MODEL сложновато. Но вроде бы удалось разобраться. Код: 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. Удалось его даже оптимизировать и избавиться от лишнего lead, теперь данный запрос выполняется менее 200мс. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.02.2017, 00:18 |
|
||
|
Помогите составить историческую таблицу
|
|||
|---|---|---|---|
|
#18+
Alibek B., всего два вопроса. 1. у Вас OLAP или OLTP? 2. model прямо в промышленную бд будете внедрять? напишите позже про эксплуатацию данного решения. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.02.2017, 11:10 |
|
||
|
Помогите составить историческую таблицу
|
|||
|---|---|---|---|
|
#18+
Встречный вопрос -- почему внедрение MODEL в производственный код вызывает недоумение? Пока вижу один ответ: тяжко будет поддерживать тем, кто не знаком с технологией Судя по вопросу OLTP или OLAP -- есть какие-то сведения, что MODEL плохо в смысле конкуренции? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.02.2017, 11:35 |
|
||
|
Помогите составить историческую таблицу
|
|||
|---|---|---|---|
|
#18+
Вячеслав Любомудров, Вячеслав, поэтому вопросы и возникли. Хотелось бы узнать насколько модель используется в промышленной эксплуатации. Ее эффективность и применимость. Все-таки есть сомнения при использовании в OLTP. Это более риторический вопрос, нежели указать на какие-то изъяны автора. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.02.2017, 11:50 |
|
||
|
Помогите составить историческую таблицу
|
|||
|---|---|---|---|
|
#18+
Как таковой эксплуатации не планируется. Модель будет использоваться при составлении ежемесячных отчетов, отчеты экспортируются в Excel и более в БД не используются. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.02.2017, 11:54 |
|
||
|
Помогите составить историческую таблицу
|
|||
|---|---|---|---|
|
#18+
Alibek B., и действительно на 50kk записей выполняется за 150~200мс? Вячеслав, авторMODEL плохо в смысле конкуренции это же чистый DDL, какая там конкуренция? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.02.2017, 12:30 |
|
||
|
Помогите составить историческую таблицу
|
|||
|---|---|---|---|
|
#18+
K790и действительно на 50kk записей выполняется за 150~200мс? Все же не 50кк, а 5кк. В таблице BM_ACTION_LOG менее 5 млн. записей, но по полям CUSTOMER_ID и ACTION_ID есть индексы, поэтому соединение выполняется быстро. На каждый CUSTOMER_ID в этой таблице записей нужного вида обычно немного (в среднем 2-3, максимум 8). В таблице CUSTOMERS более 10 тысяч записей, конечный запрос (соединение между CUSTOMERS и BM_ACTION_LOG) выполняется менее 200мс и возвращает не более 30к записей. И MODEL на этом запросе действительно выполняется быстро, около 200мс. Вообщем с MODEL пришлось некоторое время помучаться, но зато результат мне нравится больше, чем аналитические функции или использование присоединений с ODCINumberList. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.02.2017, 12:59 |
|
||
|
|

start [/forum/topic.php?fid=52&fpage=175&tid=1886437]: |
0ms |
get settings: |
5ms |
get forum list: |
9ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
34ms |
get topic data: |
6ms |
get forum data: |
2ms |
get page messages: |
35ms |
get tp. blocked users: |
1ms |
| others: | 207ms |
| total: | 303ms |

| 0 / 0 |
