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

Откуда:
Сообщений: 18
Всем привет!!!

Есть таблица Т1
typeriodsuma
12012114.5
12012103.0
1201209-2.1
12012086
22012113.1
22012101.1
22012090.1
2201208-4.0
32012110.1
3201210-1
32012090
32012084.0
4201211-0.1
4201210-1
42012094.6
42012084.0
52012111.1
52012100.1
52012094.6
5201208-4.0


надо получить
tyMinPeriodMinSumaLastSumma
12012103.04.5
22012090.13.1
32012110.10.1
52012090.11.1


то есть,
1) в столбце ty должен быть уникальные значения;
2) в столбце MinPeriod должен быть минимальный период с отрезка периодов, получаемая от последнего периода к тому, в котором suma становится не положительная;
3) в столбце MinSuma должно быть минимальное значение suma того же отрезка периодов;
4) в столбце LastSumma последнее значение, если оно положительное.
12 дек 12, 23:39    [13622765]     Ответить | Цитировать Сообщить модератору
 Re: Помогите написать запрос  [new]
Добрый Э - Эх
Guest
+ < Как вариант решения...
--
-- Тестовый набор данных:
with
  t1 (ty,period,suma) as
    (
      select *
        from (
               values
                 (1,'201211',4.5),
                 (1,'201210',3.0),
                 (1,'201209',-2.1),
                 (1,'201208',6),
                 (2,'201211',3.1),
                 (2,'201210',1.1),
                 (2,'201209',0.1),
                 (2,'201208',-4.0),
                 (3,'201211',0.1),
                 (3,'201210',-1),
                 (3,'201209',0),
                 (3,'201208',4.0),
                 (4,'201211',-0.1),
                 (4,'201210',-1),
                 (4,'201209',4.6),
                 (4,'201208',4.0),
                 (5,'201211',1.1),
                 (5,'201210',0.1),
                 (5,'201209',4.6),
                 (5,'201208',-4.0)
             ) v(i,j,l)
    )
--
-- Основной запрос (требует MS SQL Server 2012):
select ty
     , min(case f1 when 0 then period end) as min_period
     , min(case f1 when 0 then suma end) as min_suma
     , min(case f2 when 1 then suma end) as last_suma
  from (
         select t1.*
              , count(nullif(nullif(sign(suma),1),0))              -- сортировка в оконном COUNT работает
                  over(partition by ty order by period desc) as f1 -- только с версии MS SQL Server 2012 :(
              , row_number() over(partition by ty order by period desc) as f2
           from t1
       ) v
 where f1 = 0 or f2 = 1
 group by ty
having min(case f2 when 1 then suma end) >= 0
 order by ty

on-line проверка на sqlfiddle.com
13 дек 12, 06:26    [13623278]     Ответить | Цитировать Сообщить модератору
 Re: Помогите написать запрос  [new]
Добрый Э - Эх
Guest
+ < Вариант под версию MS SQL Server от 2005 и свежее
--
-- Тестовый набор данных:
with
  t1 (ty,period,suma) as
    (
      select *
        from (
               values
                 (1,'201211',4.5),
                 (1,'201210',3.0),
                 (1,'201209',-2.1),
                 (1,'201208',6),
                 (2,'201211',3.1),
                 (2,'201210',1.1),
                 (2,'201209',0.1),
                 (2,'201208',-4.0),
                 (3,'201211',0.1),
                 (3,'201210',-1),
                 (3,'201209',0),
                 (3,'201208',4.0),
                 (4,'201211',-0.1),
                 (4,'201210',-1),
                 (4,'201209',4.6),
                 (4,'201208',4.0),
                 (5,'201211',1.1),
                 (5,'201210',0.1),
                 (5,'201209',4.6),
                 (5,'201208',-4.0)
             ) v(i,j,l)
    )
--
-- Основной запрос:
select ty
     , min(case f1 when 0 then period end) as min_period
     , min(case f1 when 0 then suma end) as min_suma
     , min(case f2 when 1 then suma end) as last_suma
  from (
         select t1.*
              , (
                  select count(nullif(nullif(sign(suma),1),0))
                    from t1 t
                   where t1.ty = t.ty
                     and t1.period <= t.period
                ) as f1
              , row_number() over(partition by ty order by period desc) as f2
           from t1
       ) v
 where f1 = 0 or f2 = 1
 group by ty
having min(case f2 when 1 then suma end) >= 0
 order by ty


on-line проверка на sqlfiddle.com
13 дек 12, 06:32    [13623282]     Ответить | Цитировать Сообщить модератору
 Re: Помогите написать запрос  [new]
Knyazev Alexey
Member

Откуда: Екб -> Мск
Сообщений: 10233
Блог
мои 5 копеек:

declare @t table ( ty int,period int, suma decimal(2,1) )
insert into @t
values (1,201211,4.5)
      ,(1,201210,3.0)
      ,(1,201209,-2.1)
      ,(1,201208,6)
      ,(2,201211,3.1)
      ,(2,201210,1.1)
      ,(2,201209,0.1)
      ,(2,201208,-4.0)
      ,(3,201211,0.1)
      ,(3,201210,-1)
      ,(3,201209,0)
      ,(3,201208,4.0)
      ,(4,201211,-0.1)
      ,(4,201210,-1)
      ,(4,201209,4.6)
      ,(4,201208,4.0)
      ,(5,201211,1.1)
      ,(5,201210,0.1)
      ,(5,201209,4.6)
      ,(5,201208,-4.0);
with cte
as
(
select row_number() over (partition by ty order by period desc) id, * from @t
) 
select t1.ty, t1.period, t1.suma, t3.suma 
  from cte t1 
    inner join cte t2 on t1.id + 1 = t2.id 
           and t1.ty = t2.ty 
           and t2.suma < 0
    cross apply ( select suma from cte where ty = t1.ty and id = 1 ) t3
  where t1.ty in ( select ty from cte where id = 1 and suma > 0 );
go
13 дек 12, 06:42    [13623284]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить