|
Поиск наружения в последовательности ДАТЫ
|
|||
---|---|---|---|
#18+
Добрый день всем! Снова мне понадобилась помощь. Имеем таблицу с полями: Номер дела Номер обращения Дата начала Дата окончания Вот пример данных (для простоты разделитель столбцов точка с запятой): 642882;0;01.07.2016;28.02.2017 642882;1;01.10.2015;30.09.2016 642882;2;01.03.2016;30.04.2016 642882;3;01.05.2016;30.04.2016 642882;4;01.05.2016;30.04.2016 642882;5;01.05.2016;30.04.2016 642882;6;01.05.2016;31.05.2016 642882;7;01.06.2016;30.06.2016 642882;8;01.07.2016;30.06.2016 Пояснения по датам: При новом обращении, если дата окончания текущего обращения больше текущего месяца - ставится последний день предыдущего месяца перед месяцем обращения. Если есть несколько обращений с одного и того же месяца - в предыдущем обращении ставится дата "дата начала" минус 1, т.е. последний день предыдущего месяца. Дата начала ВСЕГДА первое число месяца дата окончания ВСЕГДА последнее число месяца Помогите найти и выдать Select таких дел с правильной датой окончания. Или, если первое невозможно, поставить правильную дату где есть нарушение. В данном примере видно нарушение в обращении 1 т.к. дата окончания 30-09-2016, а следующее обращение (2) с 01-03-2016. Соответственно дата окончания в обращении 1 должна быть 29-02-2016. Скажу честно - пока не могу понять как такое сделать. Понимаю только что нужно сравнивать дату окончания с датой начала следующего обращения. Можно предлагать создание промежуточной таблицы/столбца. Здесь ограничений не даю - ОЧЕНЬ важно получить результат: Список дел с номерами обращений и правильными датами окончания ... |
|||
:
Нравится:
Не нравится:
|
|||
04.09.2016, 21:49 |
|
Поиск наружения в последовательности ДАТЫ
|
|||
---|---|---|---|
#18+
Забыл написать - последнее обращений всегда 0 ... |
|||
:
Нравится:
Не нравится:
|
|||
04.09.2016, 21:58 |
|
Поиск наружения в последовательности ДАТЫ
|
|||
---|---|---|---|
#18+
akrushВ данном примере видно нарушение в обращении 1 т.к. дата окончания 30-09-2016, а следующее обращение (2) с 01-03-2016. Соответственно дата окончания в обращении 1 должна быть 29-02-2016. А почему нет ошибки в обращении 0, где дата окончания аж на год позже? Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
04.09.2016, 22:02 |
|
Поиск наружения в последовательности ДАТЫ
|
|||
---|---|---|---|
#18+
попробовал вот так: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14.
но выдает только 1 строку: сравнивая 0 обращение и 1 И понял что скорее всего прийдется делать через блок, но увы я не умею еще работать с блоками ... |
|||
:
Нравится:
Не нравится:
|
|||
04.09.2016, 22:08 |
|
Поиск наружения в последовательности ДАТЫ
|
|||
---|---|---|---|
#18+
akrushно выдает только 1 строку: сравнивая 0 обращение и 1 Всё правильно: ты запросил строки с нарушениями очерёдности, ты получил их. В количестве одной штуки. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
04.09.2016, 22:11 |
|
Поиск наружения в последовательности ДАТЫ
|
|||
---|---|---|---|
#18+
Dimitry Sibiryakov, потому что в 0 обращении дата окончания может быть и через год. В некоторых делах поломана именно история обращений. Не должно быть в 1 обращении дата окончания больше чем дата начала во 2 обращении. Даты должны быть последовательны, исключение - обращение с одного и того же месяца несколько раз. И даже в этом случае дата окончания меньше даты начала следующего обращения ... |
|||
:
Нравится:
Не нравится:
|
|||
04.09.2016, 22:11 |
|
Поиск наружения в последовательности ДАТЫ
|
|||
---|---|---|---|
#18+
Dimitry Sibiryakov, Дмитрий Вы мне не так давно ОЧЕНЬ помогли навести порядок с датами (когда даты хранились как текст и были неправильные, например 31-06-2016) Если возможно подскажите можно ли как-то это сделать средствами Firebird. Я уже придумал как это сделать тупым перебором в программе на делфи, но это будет очень долго. Записей в таблице около 1млн., и таких таблиц 6. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.09.2016, 22:14 |
|
Поиск наружения в последовательности ДАТЫ
|
|||
---|---|---|---|
#18+
akrushНе должно быть в 1 обращении дата окончания больше чем дата начала во 2 обращении А почему тогда в нулевом может? Какие-то переменные правила... Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
04.09.2016, 22:18 |
|
Поиск наружения в последовательности ДАТЫ
|
|||
---|---|---|---|
#18+
Dimitry Sibiryakov, нет. правила не переменные. Для простоты нахождения последнего обращения - оно всегда 0 Просто когда нужно выдать список всех последних обращений делаю select app_num from tab1 where cal_num=0 ... |
|||
:
Нравится:
Не нравится:
|
|||
04.09.2016, 22:21 |
|
Поиск наружения в последовательности ДАТЫ
|
|||
---|---|---|---|
#18+
другими словами 0 обращение всегда равно максимальное обращение +1. В принципе при следующем обращении так и делается ... |
|||
:
Нравится:
Не нравится:
|
|||
04.09.2016, 22:23 |
|
Поиск наружения в последовательности ДАТЫ
|
|||
---|---|---|---|
#18+
ИЗВИНИТЕ забыл написать что в каждом деле есть столбик "предыдущее обращение" в котором хранится номер предыдущего обращения. например для обращения 2 предыдущее обращение 1 ... |
|||
:
Нравится:
Не нравится:
|
|||
04.09.2016, 22:31 |
|
Поиск наружения в последовательности ДАТЫ
|
|||
---|---|---|---|
#18+
Обновил пример согласно добавленного столбца. Структура таблицы: Номер дела Номер обращения Номер предыдущего обращения Дата начала Дата окончания 642882;0;8;01.07.2016;28.02.2017 642882;1;0;01.10.2015;30.09.2016 642882;2;1;01.03.2016;30.04.2016 642882;3;2;01.05.2016;30.04.2016 642882;4;3;01.05.2016;30.04.2016 642882;5;4;01.05.2016;30.04.2016 642882;6;5;01.05.2016;31.05.2016 642882;7;6;01.06.2016;30.06.2016 642882;8;7;01.07.2016;30.06.2016 ... |
|||
:
Нравится:
Не нравится:
|
|||
04.09.2016, 22:34 |
|
Поиск наружения в последовательности ДАТЫ
|
|||
---|---|---|---|
#18+
akrush, Если научиться правильно задавать вопросы то вероятность получить ответ будет намного больше. В идеале предоставить скрипт создающий - таблицу - вставляющий в таблицу данные на которых можно обкатать запросы Тогда у желающих помочь не надо тратить время на вытягивание из тебя условий задачи. Может кто и понял что ты хочешь спросить, но лично мне облом вычислять ребусы. Пример чего от тебя хотелось получить: Условия: Код: 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.
Надо получить: ... ... ... Так же непонятно что ты подразумеваешь под - "правильная дата окончания" - "нарушение" И вот по этим данным твой же запрос выдает 2 записи. Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16.
... |
|||
:
Нравится:
Не нравится:
|
|||
05.09.2016, 06:55 |
|
Поиск наружения в последовательности ДАТЫ
|
|||
---|---|---|---|
#18+
akrush, Замечение по структуре данных. Если cal_num_pre - ссылка на номер предыдущего обращения то у первого обращения там должен быть не 0 а NULL. Тогда джойн по этому полю будет давать нормальные результаты, у тебя же в случае с 0 смысл получается иной. Тут играем а тут не играем. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.09.2016, 07:03 |
|
Поиск наружения в последовательности ДАТЫ
|
|||
---|---|---|---|
#18+
Ты хочешь сказать, что по одному делу не должно быть два действующих обращения. На любой момент времени. И надо сделать выборку подобных исключений. Для начала - определись с форматов выходных данных. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.09.2016, 07:34 |
|
Поиск наружения в последовательности ДАТЫ
|
|||
---|---|---|---|
#18+
А количество обращений по делу ограничено? Есть большой соблазн создать на основе твоих данных немного другую структуру , где гораздо легче можно было бы сформировать выборку. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.09.2016, 07:41 |
|
Поиск наружения в последовательности ДАТЫ
|
|||
---|---|---|---|
#18+
авторЕсли есть несколько обращений с одного и того же месяца - в предыдущем обращении ставится дата "дата начала" минус 1, т.е. последний день предыдущего месяца. А как отделить те обращения, которые фактически начались за день до месяца в котом они были закрыты, от тех, в которых была поменяна дата? ... |
|||
:
Нравится:
Не нравится:
|
|||
05.09.2016, 07:48 |
|
Поиск наружения в последовательности ДАТЫ
|
|||
---|---|---|---|
#18+
982183, основное условие - дата окончания не может быть больше чем дата начала следующего обращения ... |
|||
:
Нравится:
Не нравится:
|
|||
05.09.2016, 08:06 |
|
Поиск наружения в последовательности ДАТЫ
|
|||
---|---|---|---|
#18+
fraks, Спасибо за совет. Делаю как вы показали. Имеем (добавил еще 2 найденных дела, сколько их таких увы не знаю. Поэтому и хочу проверить) create table applic ( app_num integer, cal_num integer, cal_last integer, data_s date, data_e date ); COMMENT ON COLUMN applic.app_num is 'Номер дела'; COMMENT ON COLUMN applic.cal_num is 'Номер обращения'; COMMENT ON COLUMN applic.cal_last is 'Номер предыдущего обращения'; COMMENT ON COLUMN applic.data_s is 'Дата начала'; COMMENT ON COLUMN applic.data_e is 'Дата окончания'; insert into applic(id, app_num, cal_num, cal_num_pre, data_s, data_e) values(642882, 0, 8, '01.07.2016', '28.02.2017'); insert into applic(id, app_num, cal_num, cal_num_pre, data_s, data_e) values(642882, 1, 0, '01.10.2015', '30.09.2016'); insert into applic(id, app_num, cal_num, cal_num_pre, data_s, data_e) values(642882, 2, 1, '01.03.2016', '30.04.2016'); insert into applic(id, app_num, cal_num, cal_num_pre, data_s, data_e) values(642882, 3, 2, '01.05.2016', '30.04.2016'); insert into applic(id, app_num, cal_num, cal_num_pre, data_s, data_e) values(642882, 4, 3, '01.05.2016', '30.04.2016'); insert into applic(id, app_num, cal_num, cal_num_pre, data_s, data_e) values(642882, 5, 4, '01.05.2016', '30.04.2016'); insert into applic(id, app_num, cal_num, cal_num_pre, data_s, data_e) values(642882, 6, 5, '01.05.2016', '31.05.2016'); insert into applic(id, app_num, cal_num, cal_num_pre, data_s, data_e) values(642882, 7, 6, '01.06.2016', '30.06.2016'); insert into applic(id, app_num, cal_num, cal_num_pre, data_s, data_e) values(642882, 8, 7, '01.07.2016', '30.06.2016'); insert into applic(id, app_num, cal_num, cal_num_pre, data_s, data_e) values(600815, 0, 1, '01.12.2015', '31.12.2015'); insert into applic(id, app_num, cal_num, cal_num_pre, data_s, data_e) values(600815, 1, 0, '01.09.2015', '31.08.2016'); insert into applic(id, app_num, cal_num, cal_num_pre, data_s, data_e) values(611844, 0, 1, '01.01.2016', '31.01.2016'); insert into applic(id, app_num, cal_num, cal_num_pre, data_s, data_e) values(611844, 1, 0, '01.10.2015', '30.09.2016'); commit; Нужно получить в результате только те записи в которых дата окончания больше чем дата начала следующего обращения. Для моих 3 дел нужно получить следующее, покажу все обращения, но в идеале получить только те строчки где меняем дату(в моем случае для всех дел это обращение 1): 642882, 0, 8, '01.07.2016', '28.02.2017' 642882, 1, 0, '01.10.2015', '29.02.2016' 642882, 2, 1, '01.03.2016', '30.04.2016' 642882, 3, 2, '01.05.2016', '30.04.2016' 642882, 4, 3, '01.05.2016', '30.04.2016' 642882, 5, 4, '01.05.2016', '30.04.2016' 642882, 6, 5, '01.05.2016', '31.05.2016' 642882, 7, 6, '01.06.2016', '30.06.2016' 642882, 8, 7, '01.07.2016', '30.06.2016' 600815, 0, 1, '01.12.2015', '31.12.2015' 600815, 1, 0, '01.09.2015', '30.11.2015' 611844, 0, 1, '01.01.2016', '31.01.2016' 611844, 1, 0, '01.10.2015', '31.12.2015' ... |
|||
:
Нравится:
Не нравится:
|
|||
05.09.2016, 08:23 |
|
Поиск наружения в последовательности ДАТЫ
|
|||
---|---|---|---|
#18+
И всё же, если перевернуть структуру (что достаточно легко) На : Дело,НачДата1,КонДата1,НачДата2,КонДата2,НачДата3,КонДата3,НачДата4,КонДата4,НачДата5,КонДата5 и т.д. То задача необходимой выборки будет тривиальной. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.09.2016, 08:42 |
|
Поиск наружения в последовательности ДАТЫ
|
|||
---|---|---|---|
#18+
982183, не проблема, но есть дела где обращений 2, а есть дела где обращений 6 как тогда будет. В вначале написал что можно предлагать любые варианты, даже с промежуточными таблицами. Важно получить результат. Пока мне его удалось получить вот так: select ap.ap_app_num as app_num, ap.ap_cal_num as cal_num, ap.ap_data_s as data_s, ap.ap_Data_e as data_e, ap1.ap_cal_num as cal_err, ap1.ap_data_s as data_s_err, ap1.ap_Data_e as data_e_err, ap.ap_data_s-1 as data_repl from applic_date ap, applic_date ap1 where (ap.ap_data_e > ap1.ap_data_e) and (ap.ap_data_e > ap1.ap_data_s) and (ap1.ap_cal_num = ap.ap_cal_num - 1) and (ap1.ap_app_num = ap.ap_app_num) and (ap.ap_data_s>cast('01.01.2015' as date)) and (ap1.ap_cal_num<>0) and ((ap.ap_app_num = 600815) or(ap.ap_app_num = 611844) or(ap.ap_app_num = 642882)) union all select ap.ap_app_num as app_num, ap1.ap_cal_num as cal_num, ap1.ap_data_s as data_s, ap1.ap_Data_e as data_e, ap.ap_cal_num as cal_err, ap.ap_data_s as data_s_err, ap.ap_Data_e as data_e_err, ap1.ap_data_s-1 as data_repl from applic_date ap, applic_date ap1 where (ap.ap_data_e > ap1.ap_data_e) and (ap.ap_data_e > ap1.ap_data_s) and (ap1.ap_cal_num = ap.ap_cal_num - 1) and (ap1.ap_app_num = ap.ap_app_num) and (ap.ap_data_s>cast('01.01.2015' as date)) and (ap1.ap_cal_num=0) and ((ap.ap_app_num = 600815) or(ap.ap_app_num = 611844) or(ap.ap_app_num = 642882)) может это и некрасиво, но для моих тестовых 3 дел показывает правильно. Осталось прогрнать по всей базе. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.09.2016, 08:57 |
|
Поиск наружения в последовательности ДАТЫ
|
|||
---|---|---|---|
#18+
akrush982183, не проблема, но есть дела где обращений 2, а есть дела где обращений 6 как тогда будет. 2 или 6 тут проблем нет. Вполне легко написать соответствующее условие. Проблема будет когда будет 100 ... |
|||
:
Нравится:
Не нравится:
|
|||
05.09.2016, 09:06 |
|
Поиск наружения в последовательности ДАТЫ
|
|||
---|---|---|---|
#18+
akrushпотому что в 0 обращении дата окончания может быть и через год. В некоторых делах поломана именно история обращений. Не должно быть в 1 обращении дата окончания больше чем дата начала во 2 обращении. Даты должны быть последовательны, исключение - обращение с одного и того же месяца несколько раз. И даже в этом случае дата окончания меньше даты начала следующего обращенияНе проще ли было засунуть это правило в триггер или CHECK? ... |
|||
:
Нравится:
Не нравится:
|
|||
05.09.2016, 09:31 |
|
Поиск наружения в последовательности ДАТЫ
|
|||
---|---|---|---|
#18+
akrush, оконные функции lead и lag тебе в помощь ... |
|||
:
Нравится:
Не нравится:
|
|||
05.09.2016, 09:35 |
|
Поиск наружения в последовательности ДАТЫ
|
|||
---|---|---|---|
#18+
akrush, Пользуйся тегом SRC (PL_SQL) для выделения кода, что бы текст подсвечивался, и моноширинным шрифтом проще читать. ... |
|||
:
Нравится:
Не нравится:
|
|||
06.09.2016, 03:38 |
|
Поиск наружения в последовательности ДАТЫ
|
|||
---|---|---|---|
#18+
akrush, Еще вопрос по структуре. Зачем нужна ссылка на предыдущее обращение? Подозреваю что предыдущее обращение, если оно есть, просто имеет номер меньше чем у текущего на 1. Если этот так то ссылка не имеет смысла. Последнее обращение, которое с номером 0, перенумеровывается после закрытия? Даты окончания могут быть NULL? А у текущего с номером 0 дата закрытия сразу какая-то ставится или до закрытия и перенумеровки там NULL? ... |
|||
:
Нравится:
Не нравится:
|
|||
06.09.2016, 04:17 |
|
Поиск наружения в последовательности ДАТЫ
|
|||
---|---|---|---|
#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.
Запрос выдает обращения одного дела, отсортированные в порядке создания, нулевое в конце. Для каждого обращения выводится дата окончания предыдущего обращения, и их можно сравнить. Соответственно, первое обращение напрямую не выводится, у него нет предыдущего. В реале записи без ошибок выводить скорее всего не нужно, но так как я написал - удобно для отладки. Приведенный запрос выдает такие данные: APP_NUMCAL_NUM_PRECAL_NUMDATA_E_PREDATA_SDATA_EERR64288212 30.09.201601.03.201630.04.2016data_e_pre > data_s6428822330.04.201601.05.201630.04.2016 6428823430.04.201601.05.201630.04.2016 6428824530.04.201601.05.201630.04.2016 6428825630.04.201601.05.201631.05.2016 6428826731.05.201601.06.201630.06.2016 6428827830.06.201601.07.201630.06.2016 6428828030.06.201601.07.201628.02.2017 ... |
|||
:
Нравится:
Не нравится:
|
|||
06.09.2016, 04:57 |
|
Поиск наружения в последовательности ДАТЫ
|
|||
---|---|---|---|
#18+
И еще по структуре данных. Посмотрев профиль обнаружил что ты уже какое-то время копаешь эту унаследованную от предшественников структуру. Мне кажется что с датами у тебя неправильная установка. Нельзя допускать что бы дата окончания обращения была меньше даты начала, т.е. период времени отрцательный. В этом нет физического смысла. Попытка выдержать условие что дата начала следующего обращения обязательно должна быть больше даты окончания предыдущего такую фигню как отрицательный временной промежуток все равно не оправдывает. Более логично допустить равенство дат одного обращения, считая что это отображает ситуацию что обращение было закрыто в день начала. А так же допустить что в один день может быть несколько обращений. По большому счету может быть несколько активных обращений. Не знаю что там у тебя за физический смысл, но допустим было несколько заявок с разными вопросами, и по всем заявкам выполняется отдельная работа, возможно разными людьми. Активную заявку я бы искал по пустой дате окончания а не по ее номеру искуственно приянутому за уши в 0. И по ссылкам на предыдущее обращение. Я уже говорил но повторюсь, если это ссылка - то в случае физического отсутствия ссылки там должен быть NULL а не 0. Это я про обращение номер 1, там ссылка на предыдущее 0, но 0 у тебя означает последнее а не предыдущее. Соответственно: - на 0 ссылаться никто не может, оно же самое последнее - использовать для обработки цепочек рекурсивные запросы или процедуры нельзя, ибо у тебя ссылки закольцованы ... |
|||
:
Нравится:
Не нравится:
|
|||
06.09.2016, 07:18 |
|
Поиск наружения в последовательности ДАТЫ
|
|||
---|---|---|---|
#18+
fraks, Спасибо за совет. Я это понимаю, но пока это ДОС приложение я ничего поделать не могу. Это база на Clarion. Для поиска некоторых пробле использую родной конвертер в ДБФ, потом импорт в FB и уже потом начинаю искать проблемные участки. Вопросом переписывания программы под ВИН как раз занимаемся. Дату окончания нужно ставить обязательно т.к. это база по субсидиям на жилищно-комунальные услуги и период действия с момента обращения четко прописан. По вопросу структуры и полного описания БД, под новую программу, я еще буду писать т.к. понимаю что то что было нормально 20 лет назад, именно тогда была разработана эта система, сейчас уже не нормально и с СУБД типа Firebird можно реализовать что-то проще Огромное спасибо за код execute block. Я только стараюсь разобраться со всем этим и есть сложности. Теперь по моему конкретному вопросу у меня будет конкретный пример. Буду изучать. Спасибо :) ... |
|||
:
Нравится:
Не нравится:
|
|||
06.09.2016, 08:53 |
|
|
start [/forum/topic.php?all=1&fid=40&tid=1561976]: |
0ms |
get settings: |
11ms |
get forum list: |
12ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
53ms |
get topic data: |
11ms |
get forum data: |
2ms |
get page messages: |
47ms |
get tp. blocked users: |
1ms |
others: | 14ms |
total: | 159ms |
0 / 0 |