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

Откуда: Россия
Сообщений: 459
Здравствуйте друзья! Подскажите в вопросе. Надо промежуточную сумму. Пример ниже. Все бы легко, да код беру из CTE, и потом ещё делаю сложный код после. Потом для суммы этот сложный код приходится дублировать, что не очень удобно и красиво. Подскажите, как решить ситуацию?

DECLARE @t TABLE (f1 int, f2 int)
INSERT INTO @t VALUES (11,2),(12,1),(151,1),(112,2),(121,2),(52,1),(41,1),(32,1),(91,1),(17,1)

;WITH cte AS
(
--эта выборка[1]
	SELECT * FROM @t WHERE f1>50
)


SELECT * FROM  --выборка[2]
(
--эта подвыборка[2.1], на много строк кода (тут в примере всего на 2 строки)... как бы упрятать много строк в новый CTE...
	SELECT f2, '' AS f0, f1+1-1+1+1-2+1-1+1+1-2+1-1+1+1-2+1-1+1+1-2+1-1+1+1-2+1-1+1+1-2+11 AS f1 
	FROM cte
UNION ALL
--подвыборка[2.2]. тут надо сумму из выборки[2]. приходится полностью повторять выборку[2] на много строк. 
--Как можно повторить код. Как внедрить второй CTE ещё бы для облегчения кода?
	SELECT MAX(f2) AS f2, 'Сумма=' AS f0, SUM(f1+1-1+1+1-2+1-1+1+1-2+1-1+1+1-2+1-1+1+1-2+1-1+1+1-2+1-1+1+1-2+11) AS f1
	FROM cte
GROUP BY f2
) a
ORDER BY f2, f0


Результат как надо, тут претензий нет, просто надо упросить код, чтоб не писать f1+1-1+1+1-2+1-1+1+1-2+1-1+1+1-2+1-1+1+1-2+1-1+1+1-2+1-1+1+1-2+11 2 раза. Функции, VIEW не надо.

f2f0f1
163
1102
1162
1Сумма=327
2123
2132
2Сумма=255
1 фев 17, 11:50    [20168944]     Ответить | Цитировать Сообщить модератору
 Re: WITH(CTE) внутри основного WITH(CTE)  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6802
f50,
;WITH cte AS
(

	SELECT *, 
        f1+1-1+1+1-2+1-1+1+1-2+1-1+1+1-2+1-1+1+1-2+1-1+1+1-2+1-1+1+1-2+11 AS newf1 
        FROM @t WHERE f1>50
)
1 фев 17, 11:52    [20168953]     Ответить | Цитировать Сообщить модератору
 Re: WITH(CTE) внутри основного WITH(CTE)  [new]
Добрый Э - Эх
Guest
f50,

что мешает последовательно использовать результаты вычисления в рамках одного CTE, на каждом последующем шаге обращаясь к результатам предыдущих вычислений???
На подтип такого:

with
  cte1 as (select bla-bla-bla from TABLE ...)
, cte2 as (select .... from cte1)
, cte3 as (select .... from cte1 join cte2)

select *
  from cte3 
1 фев 17, 11:56    [20168972]     Ответить | Цитировать Сообщить модератору
 Re: WITH(CTE) внутри основного WITH(CTE)  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6802
Добрый Э - Эх
f50,

что мешает последовательно использовать результаты вычисления в рамках одного CTE, на каждом последующем шаге обращаясь к результатам предыдущих вычислений???
На подтип такого:

with
  cte1 as (select bla-bla-bla from TABLE ...)
, cte2 as (select .... from cte1)
, cte3 as (select .... from cte1 join cte2)

select *
  from cte3 
как вариант то да... но придёт o-o и будет показывать омерзительные планы таких действий :)
1 фев 17, 12:05    [20169003]     Ответить | Цитировать Сообщить модератору
 Re: WITH(CTE) внутри основного WITH(CTE)  [new]
invm
Member

Откуда: Москва
Сообщений: 9913
f50
просто надо упросить код
with cte as
(
 select
  *,
  f1+1-1+1+1-2+1-1+1+1-2+1-1+1+1-2+1-1+1+1-2+1-1+1+1-2+1-1+1+1-2+11 as f99,
  row_number() over (order by (select 1)) as rn
 from
  @t
 where
  f1 > 50
)
select
 f2, case when rn is null then 'Сумма =' else '' end, sum(f99)
from
 cte
group by
 grouping sets((f2), (rn, f2))
order by
 f2, isnull(rn, cast(0x7fffffff as int));
1 фев 17, 12:47    [20169181]     Ответить | Цитировать Сообщить модератору
 Re: WITH(CTE) внутри основного WITH(CTE)  [new]
invm
Member

Откуда: Москва
Сообщений: 9913
Так корректнее:
with cte as
(
 select
  *,
  f1+1-1+1+1-2+1-1+1+1-2+1-1+1+1-2+1-1+1+1-2+1-1+1+1-2+1-1+1+1-2+11 as f99,
  row_number() over (partition by f2 order by (select 1)) as rn
 from
  @t
 where
  f1 > 50
)
select
 f2, case when rn is null then 'Сумма =' else '' end, sum(f99)
from
 cte
group by
 grouping sets((f2), (rn, f2))
order by
 f2, isnull(rn, cast(0x7fffffff as int));
1 фев 17, 12:50    [20169193]     Ответить | Цитировать Сообщить модератору
 Re: WITH(CTE) внутри основного WITH(CTE)  [new]
f50
Member

Откуда: Россия
Сообщений: 459
Добрый Э - Эх вот это и надо было!!! Супер. Сам же что то в синтаксис не вчитался...
TaPaK, да там не упростить в самом верху, вариант Добрый Э - Эх подходит! ))
invm )) нее, так упрощать уж не надо ))) Но как вариант красивый!
1 фев 17, 12:55    [20169229]     Ответить | Цитировать Сообщить модератору
 Re: WITH(CTE) внутри основного WITH(CTE)  [new]
andrey odegov
Member

Откуда:
Сообщений: 474
DECLARE @t TABLE (f1 int, f2 int)
INSERT INTO @t VALUES (11,2),(12,1),(151,1),(112,2),(121,2),(52,1),(41,1),(32,1),(91,1),(17,1)

select *
from(select f2,
       case when grouping(f1)=1 then N'Сумма=' else '' end f0,
       case grouping(f1)
         when 1 then sum(f1+1-1+1+1-2+1-1+1+1-2+1-1+1+1-2+1-1+1+1-2+1-1+1+1-2+1-1+1+1-2+11)over(partition by f2)
         else f1+1-1+1+1-2+1-1+1+1-2+1-1+1+1-2+1-1+1+1-2+1-1+1+1-2+1-1+1+1-2+11
       end f1
     from @t
     where f1>50
     group by f2,f1 with rollup
    )t
where f2 is not null and f1 is not null
;
1 фев 17, 13:09    [20169315]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить