powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / IBM DB2, WebSphere, IMS, U2 [игнор отключен] [закрыт для гостей] / как "слить"-объединить стоящие рядом по дате записи
30 сообщений из 30, показаны все 2 страниц
как "слить"-объединить стоящие рядом по дате записи
    #37764351
skibars
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
дано, есть набор записей такого типа (неважные поля выпущены)
reg nd np kp stp
6 129241 2010-01-01 2010-06-10 1-1
6 129241 2010-06-11 2010-06-30 1-1
6 129241 2010-07-01 2010-12-31 1-1

6 129241 2005-06-11 2005-06-30 1-1
6 129241 2005-07-01 2005-12-31 1-1
получено группировкой
select distinct a.* from los3 a inner join los3 b on (a.reg,a.nd)=(b.reg,b.nd) and a.stp=b.stp
where a.reg=6 and a.nd='129241' and (days(a.np)-days(b.kp)=1 or days(b.np)-days(a.kp)=1)
order by a.stp,a.np
т.е. я искал записи в делах, где начало одного периода наступает на следующий день после предыдущего и тип (stp) периода совпадает.
Таких дел очень много. Хотел проставить ключ (чтоб использовать для последующего объединения) для таких записей, содержащий номер участка, дела, тип, минимальную и максимальную даты из набора дат для ключа. Проблема обнаружилась в том, что (как видно), может быть, что таких наборов для сливания в деле может быть больше одного. Не могу додумать, можно ли как-то разделить эти наборы, чтобы каждому присвоить свой ключ. Чувствую, что средствами просто запросов SQL нереально, значит, нужна хранимая процедура, но опыта в них почти ноль. Кто что подскажет? Массив записей для обработки - порядка 4,5 млн. штук.
p.s. дело срочное, в 24-25-го уже нужна реализация.
...
Рейтинг: 0 / 0
как "слить"-объединить стоящие рядом по дате записи
    #37764359
skibars
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
db2 v.9.7
...
Рейтинг: 0 / 0
как "слить"-объединить стоящие рядом по дате записи
    #37765825
Mark Barinstein
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
skibars,
Как-то так...
Код: 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.
with los3(reg, nd, np, kp, stp) as (values
  (6, 129241, date('2010-01-01'), date('2010-06-10'), '1-1')
, (6, 129241, date('2010-06-11'), date('2010-06-30'), '1-1')
, (6, 129241, date('2010-07-01'), date('2010-12-31'), '1-1')
-- промежуток
, (6, 129241, date('2011-03-01'), date('2011-03-31'), '1-1')
, (6, 129241, date('2011-04-01'), date('2011-04-30'), '1-1')
)
, a(lvl, reg, nd, np, kp, stp) as (
select 1, reg, nd, np, kp, stp
from los3 t1
where not exists (
select 1
from los3 t2
where t2.reg=t1.reg and t2.nd=t1.nd and t2.stp=t1.stp 
and t2.kp=t1.np - 1 day
)
  union all
select a.lvl+1, a.reg, a.nd, a.np, t.kp, a.stp
from a, los3 t
where t.reg=a.reg and t.nd=a.nd and t.stp=a.stp 
and t.np=a.kp + 1 day
)
select
  rownumber() over(order by a.reg, a.nd, a.np, a.stp) key
, a.reg, a.nd, a.np, a.kp, a.stp
from a
join (
select max(lvl) lvl, reg, nd, np, stp
from a
group by reg, nd, np, stp
) g on g.lvl=a.lvl and g.reg=a.reg and g.nd=a.nd and g.np=a.np and g.stp=a.stp

В примере считается, что по одному делу может быть несколько интервалов, между которыми есть промежутки.
...
Рейтинг: 0 / 0
как "слить"-объединить стоящие рядом по дате записи
    #37766285
skibars
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Mark Barinstein ,
благодарю за ответ, к сожалению, я только смутно понял идею, но реализовать в приложении к моей ситуации не хватает знаний.
Понял, что можно добавочно к моей базовой идее съюзать rownumber.
Процедуры умею пока писать только на уровне набора простых селектов/стандарных команд аля запрос
...
Рейтинг: 0 / 0
как "слить"-объединить стоящие рядом по дате записи
    #37766546
Mark Barinstein
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
skibarsк сожалению, я только смутно понял идею, но реализовать в приложении к моей ситуации не хватает знаний.
Понял, что можно добавочно к моей базовой идее съюзать rownumber.
Процедуры умею пока писать только на уровне набора простых селектов/стандарных команд аля запросrownumber здесь просто для нумерации укрупнённых диапазонов дел.
Это для "разделить эти наборы, чтобы каждому присвоить свой ключ".
Т.е. когда диапазоны слиты, им присваивается "ключ".
Основная идея здесь - как можно использовать Recursive Common Table Expression в DB2 для объединения в один нескольких непосредственно следующих друг за другом диапазонов дат по одной сущности (делу).

Представьте, что вы сделали из этого запроса insert select.
Код: plaintext
1.
2.
3.
insert into los3_tmp
with a(lvl, reg, nd, np, kp, stp) as (
...
Дальше вы что с этим делать хотите?
Результ этого запроса вообще вам поможет, или я неправильно понял, что вам надо?
...
Рейтинг: 0 / 0
как "слить"-объединить стоящие рядом по дате записи
    #37768764
skibars
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Mark, ещё раз благодарю за помощь. К сожалению временно поезд уже ушел, в срочном порядке делаю как получилось (знаю, что часть записей будет неправильно), но срок горит. Начиная с мая, к теме вернусь и буду не спеша разрабатывать и вкапываться для переделки.
...
Рейтинг: 0 / 0
как "слить"-объединить стоящие рядом по дате записи
    #38044259
skibars
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Mark, опять обращаюсь за помощью по той же теме (пришло время сделать как надо).
Попробовал понять логику вашего примера и переписать под известные и понятные мне конструкции (попутно изменилась немного таблица с данными, откуда надо выбрать искомое, вместо пары ключевых полей теперь одно).
итак, есть таблица, где у одного дела строки с такими временными отрезками
1988-10-03 1997-05-31
1997-07-01 1998-02-08
1998-02-17 1998-06-03
1998-06-04 1998-10-01
1998-10-07 1999-04-27
1999-04-28 2003-08-31
2003-09-01 2003-09-21
2003-09-22 2003-12-31
2004-01-01 2004-02-01
2004-02-02 2010-11-19
2010-11-20 2011-03-31
видно, что должно получиться два отрезка с 1998-02-17 по 1998-10-01 и с 1998-10-07 по 2011-03-31.
используя ваш пример, написал следующее
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
create  view aaa (lv1,sn,d1,d2,stp) as
select 1, sn, d1,d2,stp from t11_dopl t1
 where not exists
 (select 1 from t11_dopl t2 where t2.sn=t1.sn  and t2.stp=t1.stp and t2.d2=t1.d1 - 1 day) 

create view aa (lv1,sn,d1,d2,stp) as
select * from aaa union
select aaa.lv1+1, aaa.sn, aaa.d1, t.d2, aaa.stp from aaa, t11_dopl t
where t.sn=aaa.sn  and t.stp=aaa.stp and t.d1=aaa.d2 + 1 day

select rownumber() over(order by aa.sn,aa.d1,aa.stp) key, aa.sn,aa.d1,aa.d2,aa.stp from aa
  join (select max(lv1) lv1, sn, d1, stp  from aa  group by sn, d1, stp) g
  on g.lv1=aa.lv1 and g.sn=aa.sn  and g.d1=aa.d1 and g.stp=aa.stp

Получилось не то, что ожидал. Где моя ошибка?
...
Рейтинг: 0 / 0
как "слить"-объединить стоящие рядом по дате записи
    #38044371
Mark Barinstein
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
skibars...
Получилось не то, что ожидал. Где моя ошибка?
Вы сделали совсем не то, что я написал.
Код: 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.
-- Это одна команда
create view t11_dopl_v (key, sn, d1, d2, stp) as 
with a(lvl, sn, d1, d2, stp) as (
select 1, sn, d1, d2, stp
from t11_dopl t1
where not exists (
select 1
from t11_dopl t2
where t2.sn=t1.sn and t2.stp=t1.stp 
and t2.d2=t1.d1 - 1 day
)
  union all
select a.lvl+1, a.sn, a.d1, t.d2, a.stp
from a, t11_dopl t
where t.sn=a.sn and t.stp=a.stp 
and t.d1=a.d2 + 1 day
)
select
  rownumber() over(order by a.sn, a.d1, a.stp) key
, a.sn, a.d1, a.d2, a.stp
from a
join (
select max(lvl) lvl, sn, d1, stp
from a
group by sn, d1, stp
) g on g.lvl=a.lvl and g.sn=a.sn and g.d1=a.d1 and g.stp=a.stp;

...
Рейтинг: 0 / 0
как "слить"-объединить стоящие рядом по дате записи
    #38044456
CawaSPb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
skibars,

Просьба. Когда получится, посмотрите, pls, разницу планов с

вот таким вариантом:
Код: 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.
with src_data(reg, nd, np, kp, stp) as (
 values
  (6, 129241, cast('1988-10-03' as date), cast('1997-05-31' as date), '1-1'),

  (6, 129241, cast('1997-07-01' as date), cast('1998-02-08' as date), '1-1'),

  (6, 129241, cast('1998-02-17' as date), cast('1998-06-03' as date), '1-1'),
  (6, 129241, cast('1998-06-04' as date), cast('1998-10-01' as date), '1-1'),

  (6, 129241, cast('1998-10-07' as date), cast('1999-04-27' as date), '1-1'),
  (6, 129241, cast('1999-04-28' as date), cast('2003-08-31' as date), '1-1'),
  (6, 129241, cast('2003-09-01' as date), cast('2003-09-21' as date), '1-1'),
  (6, 129241, cast('2003-09-22' as date), cast('2003-12-31' as date), '1-1'),
  (6, 129241, cast('2004-01-01' as date), cast('2004-02-01' as date), '1-1'),
  (6, 129241, cast('2004-02-02' as date), cast('2010-11-19' as date), '1-1'),
  (6, 129241, cast('2010-11-20' as date), cast('2011-03-31' as date), '1-1')
),
get_prev_kp(reg, nd, np, kp, stp, prev_kp) as (
 select reg, nd, np, kp, stp, 
        LAG(kp) OVER (PARTITION BY reg, nd, stp order by np) as prev_kp -- значение kp от "предыдущей строки"
 from src_data
),
gen_seq_inc(reg, nd, np, kp, stp, seq_inc) as (
 select reg, nd, np, kp, stp,
        case when prev_kp + 1 day = np then 0  -- та же последовательность
		     else 1                            -- новый интервал
	    end as seq_inc -- increment номера последовательности
 from get_prev_kp
),
gen_seq_num(reg, nd, np, kp, stp, seq_num) as (
 select reg, nd, np, kp, stp,
        sum(seq_inc) over(PARTITION BY reg, nd, stp 
		                  order by nd ROWS UNBOUNDED PRECEDING
				     ) as seq_num -- номер последовательности (считаем как сумму инкрементов по всем предыдущим строкам)
 from gen_seq_inc
)
select reg, nd, min(np), max(kp), stp
from gen_seq_num
group by reg, nd, stp, seq_num;


или
в новых терминах:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
with get_prev_d2(sn, d1, d2, stp, prev_d2) as (
 select sn, d1, d2, stp, 
        LAG(d2) OVER (PARTITION BY sn, stp order by d1) as prev_d2 -- значение d2 от "предыдущей строки"
 from t11_dopl
),
gen_seq_inc(sn, d1, d2, stp, seq_inc) as (
 select sn, d1, d2, stp,
        case when prev_d2 + 1 day = d1 then 0  -- та же последовательность
             else 1                            -- новый интервал
        end as seq_inc -- increment номера последовательности
 from get_prev_d2
),
gen_seq_num(sn, d1, d2, stp, seq_num) as (
 select sn, d1, d2, stp,
        sum(seq_inc) over(PARTITION BY sn, stp 
                          order by d1 ROWS UNBOUNDED PRECEDING
                     ) as seq_num -- номер последовательности (считаем как сумму инкрементов по всем предыдущим строкам)
 from gen_seq_inc
)
select sn, min(d1), max(d2), stp
from gen_seq_num
group by sn, stp, seq_num;



Очень интересно.
...
Рейтинг: 0 / 0
как "слить"-объединить стоящие рядом по дате записи
    #38044833
skibars...
d1d21988-10-031997-05-311997-07-011998-02-081998-02-171998-06-031998-06-041998-10-011998-10-071999-04-271999-04-282003-08-312003-09-012003-09-212003-09-222003-12-312004-01-012004-02-012004-02-022010-11-192010-11-202011-03-31...
видно, что должно получиться два отрезка с 1998-02-17 по 1998-10-01 и с 1998-10-07 по 2011-03-31.

По исходным данным видно как раз несколько иное. Лично я там вижу четыре диапазона:
d1d21988-10-031997-05-311997-07-011998-02-081998-02-171998-10-011998-10-072011-03-31
Или я как-то не так понял принцип объединения малых интервалов в более крупный?
...
Рейтинг: 0 / 0
как "слить"-объединить стоящие рядом по дате записи
    #38044835
А вообще, запрос мог бы иметь примерно такой вид:
Код: 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.
--
-- Тестовый набор данных 
-- (сорри за немного оракловый акцент, но он-лайн тестовую базу DB2 найти не смог):
with
  t11_dopl(d1, d2) as 
    (
      select date'1988-10-03', date'1997-05-31' from dual union all
      select date'1997-07-01', date'1998-02-08' from dual union all
      select date'1998-02-17', date'1998-06-03' from dual union all
      select date'1998-06-04', date'1998-10-01' from dual union all
      select date'1998-10-07', date'1999-04-27' from dual union all
      select date'1999-04-28', date'2003-08-31' from dual union all
      select date'2003-09-01', date'2003-09-21' from dual union all
      select date'2003-09-22', date'2003-12-31' from dual union all
      select date'2004-01-01', date'2004-02-01' from dual union all
      select date'2004-02-02', date'2010-11-19' from dual union all
      select date'2010-11-20', date'2011-03-31' from dual
    )
--
-- Основной запрос (вроде все конструкции аналогичны "местному" синтаксису):
select min(d1) as x_d1, max(d2) as x_d2
  from (
         select d1, d2, sum(sog) over(order by d1,d2) as grp_id
           from (
                  select d1, d2, 
                         case 
                           when d1 <= max(d2 + 1 day) over(order by d1, d2 
                                                            rows between unbounded preceding
                                                             and 1 preceding) 
                             then 0 
                           else 1 
                         end as sog -- sog = start_of_group :)
                    from t11_dopl
                )
       )
 group by grp_id
 order by 1

Query finished, retrieving results...

    X_D1          X_D2
-----------   -----------
03-окт-1988   31-май-1997
01-июл-1997   08-фев-1998
17-фев-1998   01-окт-1998
07-окт-1998   31-мар-2011

4 row(s) retrieved
...
Рейтинг: 0 / 0
как "слить"-объединить стоящие рядом по дате записи
    #38045076
skibars
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Mark, Добрый Э - Эх, CawaSPb, благодарю за ответы. все получилось, можно использовать на реальных данных. Постараюсь допонять до конца.

Добрый Э - Эх. Вообще-то да, верно всё понято, просто я не конца объяснил. В конечном итоге получаются эти 4 интервала, просто для меня главной сложностью было выделить и объединить то, что подлежит этой операции. Отдельные записи, которые слитию не подлежат, можно добавиться уже потом. Хотя, как теперь вижу, можно делать всё разом.

CawaSPb, план запроса у меня CC вообще не показывает. Возможно, не хватает прав (я не админ базы), а может, что-то ещё
...
Рейтинг: 0 / 0
как "слить"-объединить стоящие рядом по дате записи
    #38045346
CawaSPb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
skibars,

А что именно говорит?
Вероятно просто explain таблицы для текущей схемы отсутствуют (explain ищет таблицы для промежуточного сохранения информации в текущей схеме).

Можно их с помощью SYSINSTALLOBJECTS procedure сделать:
Код: sql
1.
call SYSPROC.SYSINSTALLOBJECTS('EXPLAIN', 'C', 'YourCoolTablespace', 'YourSchema');


(попросить сделать кого-либо с достаточными правами).

Можно сделать самому с помощью sqllib/misc/explain.dll.


По первому варианту можно сделать одну общую копию explain таблиц и пробросить к ним alias'ы.
...
Рейтинг: 0 / 0
как "слить"-объединить стоящие рядом по дате записи
    #38046436
skibars
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
CawaSPb,
в sqllib/misc/ у меня нет explain.dll, там всего лишь одна (другая) длл-ка.

дали мне временно админа, попробовал выполнить указанную процедуру вот так
call SYSPROC.SYSINSTALLOBJECTS('EXPLAIN', 'C', 'systoolsspace', 'ka11');
пространства разные пробовал (все 5, что вижу в списке table spaces), на все дает ошибку ... is an undefined name. SQLSTATE=42704.

То же самое происходило и при попытках выполнения под моим пользователем
...
Рейтинг: 0 / 0
как "слить"-объединить стоящие рядом по дате записи
    #38046548
skibars
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
таблиц explain-, да в нужной схеме нет. план запроса ничего не говорит, просто серое окошко без текста
...
Рейтинг: 0 / 0
как "слить"-объединить стоящие рядом по дате записи
    #38046792
CawaSPb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
skibars,

explain.d d l, конечно.

Попробовать
call SYSPROC.SYSINSTALLOBJECTS('EXPLAIN', 'C', cast(null as VARCHAR(128)), 'ka11');
...
Рейтинг: 0 / 0
как "слить"-объединить стоящие рядом по дате записи
    #38046843
skibars
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
попробовал. выдало: Return Status = 0

вставил предложенный запрос по датам, он выполнился, показал выборку, план по-прежнему пуст
...
Рейтинг: 0 / 0
как "слить"-объединить стоящие рядом по дате записи
    #38046930
CawaSPb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
skibars,

А вот так:
Код: plaintext
db2expln -database  dbname  -user ka11  pwd  -output plan.txt -stmtfile query.sql -terminator ";" -graph -opids

Предварительно запихнув запрос в query.sql
...
Рейтинг: 0 / 0
как "слить"-объединить стоящие рядом по дате записи
    #38047058
skibars
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
записал запрос в c:\query.sql
в обычной ком.строке набил:
db2expln -database actuar -user up000117 [тут пароль] -output c:\plan.txt -stmtfile c:\query.sql -terminator ";" -graph -opids
выдал это:
Error during explain call.

Message Text =
SQL0444N Routine "explain" (specific name "SQL121121142052360") is
implemented with code in library or path "\db2exsrv", function "explain"
which cannot be accessed. Reason code: "4". SQLSTATE=42724
и далее еще параметры всякие...
пустой файл c:\plan.txt создался.
-на всякий случай: у меня под одним юзером несколько схем, тут видно, что юзер не= ka11.
ту же ошибку пишет для админа
...
Рейтинг: 0 / 0
как "слить"-объединить стоящие рядом по дате записи
    #38364308
skibars
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Mark
Добрый Э - Эх

опять прошу помощи по этой же теме.
В той же таблице в каждой записи есть ещё и поля с суммами дней (посчитанные разными способами). Есть ли способ включить в уже предложенные запросы объединения строк по датам и объединение по суммам (например, поля s1, s2) или такого способа нет, и мне придётся уже потом искать способ вставки в поля новой таблицы сгруппированных сумм?

Самостоятельно пока не получилось - по версии Марка не разрешает группировать одновременно и для дат, и для сумм.

По версии Э - Эх суммирует, но обнаружилась проблема группировки в сложных случаях набора дат, например:
reg nd np kp st ns sev
6 129241 1990-02-12 1991-10-14 1-2 0 1
6 129241 1991-10-15 1995-09-30 1-3 0 1
6 129241 1995-11-04 2001-12-31 1-2 0 1
6 129241 2002-01-01 2009-12-31 1-2 0 1

Тут период '1-2' неверно объединяется, как если бы внутри не было периода '1-3'

мой вариант:
select reg,nd,st,ns,sev,min(np) as x_d1, max(kp) as x_d2,sum(s1d),sum(s2d),sum(s3d)
from (select reg,nd,st,ns,sev,np, kp, s1d,s2d,s3d,sum(sog) over(order by reg,nd,st,ns,sev,np) as grp_id
from (select reg,nd,st,ns,sev,np, kp,s1d,s2d,s3d,
case when np<=max(kp+1 day) over(order by reg,nd,st,ns,sev,np rows between unbounded preceding and 1 preceding) then 0 else 1 end as sog
from loz11 where reg=6 and nd='129241') ) group by reg,nd,st,ns,sev,grp_id order by 1,x_d1
...
Рейтинг: 0 / 0
как "слить"-объединить стоящие рядом по дате записи
    #38364642
Mark Barinstein
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
skibars
Код: plaintext
1.
2.
3.
4.
5.
reg	nd	np		kp		st	ns	sev
6	129241	1990-02-12	1991-10-14	1-2 	0	1
6	129241	1991-10-15	1995-09-30	1-3 	0	1
6	129241	1995-11-04	2001-12-31	1-2 	0	1
6	129241	2002-01-01	2009-12-31	1-2 	0	1
Поля ns и sev входят в набор ключевых полей объединения?
Т.е. это (reg, nd, st) или (reg, nd, st, ns, sev)?
...
Рейтинг: 0 / 0
как "слить"-объединить стоящие рядом по дате записи
    #38364648
skibars
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Mark Barinstein,

да, все эти поля - ключи для группировки: reg,nd,st,ns,sev
...
Рейтинг: 0 / 0
как "слить"-объединить стоящие рядом по дате записи
    #38364691
Mark Barinstein
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
skibars,

Если я правльно понял задачу - просуммировать о полю внутри группы, то как-то так
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
with t (reg, nd, np, kp, st, ns, sev, s1) as (values
  (6, 129241, date('1990-02-12'), date('1991-10-14'), '1-2', 0, 1, 1)
, (6, 129241, date('1991-10-15'), date('1995-09-30'), '1-3', 0, 1, 10)
, (6, 129241, date('1995-11-04'), date('2001-12-31'), '1-2', 0, 1, 2)
, (6, 129241, date('2002-01-01'), date('2009-12-31'), '1-2', 0, 1, 3)
)
, a (lvl, reg, nd, st, ns, sev, np, kp, s1) as (
select 1 as lvl, a.reg, a.nd, a.st, a.ns, a.sev, a.np, a.kp, a.s1
from t a
where not exists (
select 1 from t b 
where b.reg=a.reg and b.nd=a.nd and b.st=a.st and b.ns=a.ns and b.sev=a.sev and b.kp=a.np - 1 day)
  union all
select a.lvl+1, a.reg, a.nd, a.st, a.ns, a.sev, a.np, t.kp, a.s1+t.s1
from a, t
where t.reg=a.reg and t.nd=a.nd and t.st=a.st and t.ns=a.ns and t.sev=a.sev and t.np=a.kp + 1 day
)
select a.*
from a
join (
select max(lvl) lvl, reg, nd, st, ns, sev, np from a group by reg, nd, st, ns, sev, np
) g on g.lvl=a.lvl and g.reg=a.reg and g.nd=a.nd and g.st=a.st and g.ns=a.ns and g.sev=a.sev and g.np=a.np

...
Рейтинг: 0 / 0
как "слить"-объединить стоящие рядом по дате записи
    #38364988
skibars
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Mark
ваш пример работает.
попробовал переписать под свой запрос (учитывая фактические поля в таблице) так

create view loz_v (key, reg,nd, d1, d2, stkt,nspis2,sever,s1d) as
with a (lvl, reg,nd, nper,kper, stkt,nspis2,sever,s1d) as
(select 1, reg,nd, stkt,nspis2,sever, nper,kper,s1d from loz11 t1
where reg=6 and nd='129241' and
not exists (select 1 from loz11 t2 where (t2.reg,t2.nd,t2.stkt,t2.nspis2,t2.sever)=(t1.reg,t1.nd,t1.stkt,t1.nspis2,t1.sever) and t2.kper=t1.nper-1 day)
union all
select a.lvl+1, a.reg,a.nd, a.stkt,a.nspis2,a.sever, a.nper,t.kper,a.s1d+t.s1d from a, loz11 t
where (t.reg,t.nd,t.stkt,t.nspis2,t.sever)=(a.reg,a.nd,a.stkt,a.nspis2,a.sever) and t.nper=a.kper + 1 day)
select a.* from a join
(select max(lvl) lvl, reg,nd, stkt,nspis2,sever, nper from a group by reg,nd, stkt,nspis2,sever, nper) g
on g.lvl=a.lvl and (g.reg,g.nd,g.stkt,g.nspis2,g.sever,g.nper)=(a.reg,a.nd,a.stkt,a.nspis2,a.sever,a.nper)

при попытке выполнения (без создания вью) ругается
Error: SQL0401N The data types of the operands for the operation "=" are not compatible

Перепроверил все =, так и не понял, где несовместимые типы.

И ещё: раньше в конце была конструкция с select rownumber() over(order by...
теперь без неё даты не упорядочиваются
...
Рейтинг: 0 / 0
как "слить"-объединить стоящие рядом по дате записи
    #38365077
Mark Barinstein
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
skibars,

Дайте вывод команды:
Код: sql
1.
2.
describe
select reg,nd, stkt,nspis2,sever, nper,kper,s1d from loz11


Добавьте 'order by' по нужным полям в конце запроса.
...
Рейтинг: 0 / 0
как "слить"-объединить стоящие рядом по дате записи
    #38365164
skibars
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Mark,

SQLDA Information
sqldaid : SQLDA sqldabc: 896 sqln: 20 sqld: 8
Column Information
sqltype sqllen sqlname.data sqlname.length
-------------------- ------ ------------------------------ --------------
501 SMALLINT 2 REG 3
453 CHARACTER 6 ND 2
453 CHARACTER 4 STKT 4
485 DECIMAL 3, 0 NSPIS2 6
485 DECIMAL 1, 0 SEVER 5
385 DATE 10 NPER 4
385 DATE 10 KPER 4
497 INTEGER 4 S1D 3
...
Рейтинг: 0 / 0
как "слить"-объединить стоящие рядом по дате записи
    #38365196
Mark Barinstein
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
skibars,

Порядок полей неправильный
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
with a (lvl, reg,nd, stkt,nspis2,sever, nper,kper, s1d) as
with a (lvl, reg,nd, nper,kper, stkt,nspis2,sever, s1d) as
(select 1, reg,nd, stkt,nspis2,sever, nper,kper,s1d from loz11 t1
where reg=6 and nd='129241' and
not exists (select 1 from loz11 t2 where (t2.reg,t2.nd,t2.stkt,t2.nspis2,t2.sever)=(t1.reg,t1.nd,t1.stkt,t1.nspis2,t1.sever) and t2.kper=t1.nper-1 day)
union all
select a.lvl+1, a.reg,a.nd, a.stkt,a.nspis2,a.sever, a.nper,t.kper,a.s1d+t.s1d from a, loz11 t
where (t.reg,t.nd,t.stkt,t.nspis2,t.sever)=(a.reg,a.nd,a.stkt,a.nspis2,a.sever) and t.nper=a.kper + 1 day)
select a.* from a join
(select max(lvl) lvl, reg,nd, stkt,nspis2,sever, nper from a group by reg,nd, stkt,nspis2,sever, nper) g
on g.lvl=a.lvl and (g.reg,g.nd,g.stkt,g.nspis2,g.sever,g.nper)=(a.reg,a.nd,a.stkt,a.nspis2,a.sever,a.nper)
...
Рейтинг: 0 / 0
как "слить"-объединить стоящие рядом по дате записи
    #38365211
skibars
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Mark Barinstein ,
ура! всё заработало, весьма благодарен, проверил и для трёх сумм вместо одной (там только надо чтоб поля сумм были не NULL, но это мелочь)
...
Рейтинг: 0 / 0
как "слить"-объединить стоящие рядом по дате записи
    #38365594
skibars...все эти поля - ключи для группировки: reg,nd,st,ns,sev

Тогда в моем решение расширяем конструкцию окна разбивкой на группы и включаем "ключевые поля" в условия итоговой группировки:

Код: 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.
--
-- Тестовый набор данных 
-- (сорри за немного оракловый акцент, но он-лайн тестовую базу DB2 найти не смог):
with
  t11_dopl(reg, nd, np, kp, st, ns, sev) as 
    (
      select 6, 129241, date'1990-02-12', date'1991-10-14', '1-2', 0, 1 from dual union all
      select 6, 129241, date'1991-10-15', date'1995-09-30', '1-3', 0, 1 from dual union all
      select 6, 129241, date'1995-11-04', date'2001-12-31', '1-2', 0, 1 from dual union all
      select 6, 129241, date'2002-01-01', date'2009-12-31', '1-2', 0, 1 from dual
    )
--
-- Основной запрос (вроде все конструкции аналогичны "местному" синтаксису):
select reg, nd, min(np) as x_np, max(kp) as x_kp, st, ns, sev
  from (
         select reg, nd, st, ns, sev, np, kp, 
                sum(sog) over(partition by reg, nd, st, ns, sev
                                  order by np,kp) as grp_id
           from (
                  select reg, nd, st, ns, sev, np, kp, 
                         case 
                           when np <= max(kp + 1 day) over(partition by reg, nd, st, ns, sev
                                                           order by np, kp 
                                                            rows between unbounded preceding
                                                             and 1 preceding) 
                             then 0 
                           else 1 
                         end as sog -- sog = start_of_group :)
                    from t11_dopl
                )
       )
 group by reg, nd, st, ns, sev, grp_id
 order by reg, nd, st, ns, sev, x_np

on-line проверка на sqlfiddle.com
...
Рейтинг: 0 / 0
как "слить"-объединить стоящие рядом по дате записи
    #38371551
skibars
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый Э - Эх,

dual - неизвестное имя для db2, нашёл замену - SYSIBM.SYSDUMMY1 :). работает! целиком тащить из таблицы пока не пробовал.
ну и ещё ведь надо из других полей дни суммировать, ну это уже не горит... будет интересно и время - сам попробую дополнить.
Благодарю!
...
Рейтинг: 0 / 0
30 сообщений из 30, показаны все 2 страниц
Форумы / IBM DB2, WebSphere, IMS, U2 [игнор отключен] [закрыт для гостей] / как "слить"-объединить стоящие рядом по дате записи
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]