|
Поиск наружения в последовательности ДАТЫ
|
|||
---|---|---|---|
#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 |
|
|
start [/forum/topic.php?fid=40&msg=39303496&tid=1561976]: |
0ms |
get settings: |
8ms |
get forum list: |
12ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
47ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
57ms |
get tp. blocked users: |
1ms |
others: | 299ms |
total: | 442ms |
0 / 0 |