Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Помогите решить сложную интересную задачу  [new]
AlexKM2020
Member

Откуда:
Сообщений: 19
Добрый день, коллеги.
Возникла задача, не простая...
1. Есть динамический диапозон, допустим: с @from и @to и этот диапозон необходимо последовательно начитать:
-- Переменные
declare @from int = -200
       ,@to int = 300;
-- таблица, в которую начитываем
if OBJECT_ID('tempdb..#t') is not null
   drop table #t;
create table #t(
                ID int
			   ,val float
               );	   
;
with cte
as
(
select a = @from
union all
select a + 1
from cte
where a < @to
)
insert into #t
      (
       ID
      )
select a
from cte
option (maxrecursion 0);


(пока всё нормально)

Собственно вопрос, коллеги
2. Есть таблица с неопределенным колшичеством строк/диапозоном значений пример:
-- Собственно вопрос, коллеги
2. Есть таблица с неопределенным колшичеством строк/диапозоном значений пример:
if OBJECT_ID('tempdb..#tval') is not null
   drop table #tval
create table #tval(
                   ID int
			      ,val float
                  );
insert into #tval(ID, val);
values (-300, 10),(-250, 17),(-90, 12),(10, 14),(200, 11),(500, 10);


Количество строк/диапазонов значений не определено, диапазоны и значения, соответственно:
с -250 по -90 (потому что интервал начинается с 200, значение -300 не попадает, перед ним есть ближайшее -250) значение 17
с -90 по 10 значение 12
с 10 по 200 значение 14
с 200 по 300 (потому что интервал закрызся на 300) значение 11

С выбором интервалов это понятно и просто.

Собственно сам вопрос:
Есть ли возможность и если есть, то как без цикла, скорее всего в рекурсии, всем знасениям диапозона проставить значения интервалов?

Пример для наглядности:
-92 17
-91 17
-90 17
-89 12
-88 12
.....
8 12
9 12
10 14
11 14
и т.д.

P.S.
Вариант с параметризацией тоже не подходит, текст запроса в цикле начитывается ...
Надо без циклов ...

Коллеги, если есть идиеи, варианты, поделитесь пожалуйста.

Спасибо.
6 авг 19, 09:49    [21942630]     Ответить | Цитировать Сообщить модератору
 Re: Помогите решить сложную интересную задачу  [new]
Minamoto
Member

Откуда: Москва
Сообщений: 1162
AlexKM2020,

with cte
as
(
select a = @from
union all
select a + 1
from cte
where a < @to
)
insert into #t
      (
       ID, val
      )
select cte.a, tv.val
from cte
    outer apply (select top (1) val from #tval tv where tv.ID < cte.a order by tv.ID desc) tv
     
option (maxrecursion 0);
6 авг 19, 09:57    [21942635]     Ответить | Цитировать Сообщить модератору
 Re: Помогите решить сложную интересную задачу  [new]
AlexKM2020
Member

Откуда:
Сообщений: 19
Спасибо огромное!!!
оператор APPLY вылетел из головы )))
Заменил outer на cross и теперь без нулов, ещё раз спасибо!!!
6 авг 19, 10:24    [21942662]     Ответить | Цитировать Сообщить модератору
 Re: Помогите решить сложную интересную задачу  [new]
invm
Member

Откуда: Москва
Сообщений: 9116
AlexKM2020,

Без рекурсии и временной таблицы:
with d as
(
 select d from (values (0), (1), (0), (0), (0), (0), (0), (0), (0), (0)) t(d)
),
n as
(
 select
  row_number() over (order by (select 1)) as n
 from
  d a cross join
  d b cross join
  d c cross join
  d d
),
t as
(
 select ID, val, lead(ID, 1, ID) over (order by ID) as next_ID from @tval where ID between @from and @to
)
select
 t.ID + a.n, t.val
from
 t cross apply
 (select top (t.next_ID - t.ID) n - 1 from n) a(n);

Если заведете служебную таблицу с натуральными числами, то можно еще проще.
6 авг 19, 10:58    [21942695]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить