Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Разбиение пересекающихся интервалов на подинтервалы / 16 сообщений из 16, страница 1 из 1
04.08.2018, 13:50
    #39683308
fsmk
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Разбиение пересекающихся интервалов на подинтервалы
Добрый день всем! Скажу сразу, поиском пользовался, варианты не совсем рабочие находил. Суть проблемы:

есть табличка интервалов например на прямой, координаты интервалов:

x1 x2
1 10
1 10
1 10
1 10
...
Рейтинг: 0 / 0
04.08.2018, 13:54
    #39683309
uaggster
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Разбиение пересекающихся интервалов на подинтервалы
...
Рейтинг: 0 / 0
04.08.2018, 13:56
    #39683310
fsmk
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Разбиение пересекающихся интервалов на подинтервалы
случайно запостил, не нашел как отредактировать пост пишу дальше:

есть табличка интервалов например на прямой, координаты интервалов:

x1 x2
1 10
2 11
5 5

Нужно разбить на подинтервалы и получить:

1 2
2 5
5 10
10 11
...
Рейтинг: 0 / 0
04.08.2018, 14:22
    #39683313
fsmk
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Разбиение пересекающихся интервалов на подинтервалы
uaggster,

не совсем то. мне по сути острова нужно тоже делить.
...
Рейтинг: 0 / 0
04.08.2018, 14:32
    #39683316
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Разбиение пересекающихся интервалов на подинтервалы
Код: 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.
declare @t table(x1 int, x2 int);

insert into @t
values
 (1, 10), (2, 12), (5, 5);

with a(x) as
(
 select x1 from @t
 union all
 select x2 from @t
), b as
(
 select x, row_number() over (order by x) as rn from a
)
select
 b1.x, b2.x
from
 b b1 join
 b b2 on b2.rn = b1.rn + 1
where
 b2.x > b1.x
order by
 b1.x;
...
Рейтинг: 0 / 0
04.08.2018, 14:34
    #39683317
Deff
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Разбиение пересекающихся интервалов на подинтервалы
fsmkслучайно запостил, не нашел как отредактировать пост пишу дальше:

есть табличка интервалов например на прямой, координаты интервалов:

x1 x2
1 10
2 11
5 5

Нужно разбить на подинтервалы и получить:

1 2
2 5
5 10
10 11Эта задача не решается в один поток. SQL тут не помощник.
Используй другие методы для решения алгоритмических задач.
...
Рейтинг: 0 / 0
04.08.2018, 14:49
    #39683319
fsmk
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Разбиение пересекающихся интервалов на подинтервалы
invm, благодарю!!!!!
...
Рейтинг: 0 / 0
06.08.2018, 11:23
    #39683624
fsmk
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Разбиение пересекающихся интервалов на подинтервалы
invm,

insert into @t
values
(1, 2), (3, 5), (3, 7);

с такими значениями выдает лишний интервал 2 - 3, от ведь не пересекается?
...
Рейтинг: 0 / 0
06.08.2018, 12:33
    #39683662
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Разбиение пересекающихся интервалов на подинтервалы
fsmk,

Разбейте исходный набор на два - интервалы, которые не пересекаются с другими и остальные.
Первый пойдет напрямую в результат, а ко второму примените показанное преобразование.
...
Рейтинг: 0 / 0
06.08.2018, 13:19
    #39683703
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Разбиение пересекающихся интервалов на подинтервалы
Если по рабоче-крестьянски, то можно так:

Код: 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.
with test (start,stop) as (
select 1,2 union all
select 3,4 union all
select 4,5 union all
select 6,8 union all
select 7,9 union all
select 8,10 union all
select 11,14 union all
select 12,13
),
total(point,weight) as (
select start,1 from test
union all
select stop,-1 from test
),
weights (point, weight, rn) as (
select t1.point, sum(t2.weight), row_number() over (order by t1.point)
from total t1, total t2
where t1.point >= t2.point
group by t1.point)
select t1.point start, t2.point stop
from weights t1, weights t2
where t1.rn=t2.rn-1
and t1.weight > 0;
...
Рейтинг: 0 / 0
06.08.2018, 22:22
    #39683987
demind10
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Разбиение пересекающихся интервалов на подинтервалы
fsmk, можно в решение invm добавить проверку на попадание внутрь существующего интервала.
Код: 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.
declare @t table(x1 int, x2 int);

insert into @t
values
 (1, 10), (2, 12), (5, 5),(6,13),(15,20);

with a(x) as
(
 select x1 from @t
 union all
 select x2 from @t
), b as
(
 select x, row_number() over (order by x) as rn from a
)
select *
from (
select
 b1.x, b2.x as y
from
 b b1 join
 b b2 on b2.rn = b1.rn + 1
where
 b2.x > b1.x
--order by
-- b1.x
 ) D
 where exists (select * from @t where x>=x1 and y<=x2)
 order by x;
...
Рейтинг: 0 / 0
07.08.2018, 06:18
    #39684025
Щукина Анна
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Разбиение пересекающихся интервалов на подинтервалы
fsmk,
сборная солянка на основе лучших моментов из предыдущих решений + небольшая изюминка собственного приготовления... :)
Код: 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.
with
-- Исходные данные:
  intervals(x1, x2) as
    (
      select * 
        from (
               values 
                 (-5, -3),
                 ( 1,  2),
                 ( 2,  5),
                 ( 5, 10),
                 (10, 11),
                 (15, 18)
             ) v(x1,x2)
    )
-- Разворот интервалов в точки (можно использовать UNPIVOT при желании)
, point (p, f) as
    (
      select x1, 1 f from intervals
      union all
      select x2, -1 f from intervals
    )
-- Нумерация точек и расчет "эрланга"
, numeredPoint (p, rn, erlang) as
    (
      select p
           , row_number() over (order by p) as rn
           , sum(f) over(order by p) erlang
       from point
    )
, newIntervals (newX1, newX2) as
-- Свёртка точек в новые интервалы + фильтрация "мусора"
    (
      select p1.p as newX1
           , p2.p as newX2
        from numeredPoint p1
        join numeredPoint p2
          on p2.rn = p1.rn + 1
       where p2.p > p1.p
         and p1.erlang > 0
    )
-- Показ результата:
select * 
  from newIntervals


желающим проверок - ссылка на sqlfiddle.com
...
Рейтинг: 0 / 0
07.08.2018, 07:23
    #39684037
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Разбиение пересекающихся интервалов на подинтервалы
Щукина Анна , Вам не кажется, что с учётом
Код: sql
1.
row_number() over (order by p) as rn

и
Код: sql
1.
on p2.rn = p1.rn + 1

условие
Код: sql
1.
where p2.p > p1.p

является избыточным?
...
Рейтинг: 0 / 0
07.08.2018, 07:25
    #39684038
Щукина Анна
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Разбиение пересекающихся интервалов на подинтервалы
Akina,

все данные для тестирования доступны. попробуйте с условием, без условия и почувствуйте разницу ;)
...
Рейтинг: 0 / 0
07.08.2018, 08:31
    #39684047
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Разбиение пересекающихся интервалов на подинтервалы
Щукина Анна , да, не посмотрел, что свёртка выполняется именно на этом этапе, а не на предыдущем. Сорри.
...
Рейтинг: 0 / 0
07.08.2018, 08:33
    #39684049
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Разбиение пересекающихся интервалов на подинтервалы
PS. Старайтесь всё же пользоваться менее тормозными fiddle-ресурсами. Скажем, db<>fiddle или db-fiddle .
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Разбиение пересекающихся интервалов на подинтервалы / 16 сообщений из 16, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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