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

Откуда:
Сообщений: 311
добрый день!
прошу помощи в группировке данных
данные
declare @t table (i int, d datetime, t varchar(10))
insert into @t
values(10,'20120101','a'),
(20,'20120501','b'),
(30,'20120601','b'),
(15,'20120708','a')

select * from @t

Таблица вбросов денег на счет
нужно найти суммарные вбросы по типам (a и b)
решается достаточно прозаично

select 
	sum(case when t='a' then i else 0 end) sum_a,
	sum(case when t='b' then i else 0 end) sum_b
from @t

но, нужно получить еще дату и сумму первого достаточно большого вброса денег (скажем больше 20) и тип этого должен быть "b"
то есть должно получиться
sum_a sum_b mindate i_first
25 50 2012-05-01 20

с датой еще более менее понятно

select 
	sum(case when t='a' then i else 0 end) sum_a,
	sum(case when t='b' then i else 0 end) sum_b,
	min(case when t='b' and i >= 20 then d else '20501231' end) mindate
from @t

но вот что делать с суммой

неужели подзапрос?
1 окт 12, 16:25    [13250812]     Ответить | Цитировать Сообщить модератору
 Re: группировка  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
Да, отдельным запросом Top ...

Разрешаю. :]
1 окт 12, 16:49    [13251041]     Ответить | Цитировать Сообщить модератору
 Re: группировка  [new]
bacalavr
Member

Откуда:
Сообщений: 311
эх
наверно подошел бы FIRST_VALUE но он с 12 сервера только
а тут 2008 r2
1 окт 12, 16:54    [13251099]     Ответить | Цитировать Сообщить модератору
 Re: группировка  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
bacalavr, не пошёл бы - тут явная группировка.

А при агрегации мутузить сервер дополнительным объёмом данных - тормоз.
Поэтому после поиска нужной даты (ID строки) остальные данный подымутся по индексу - одной строкой. Это дёшево.

Логически, в задаче две независимые вещи.
1 окт 12, 18:11    [13251781]     Ответить | Цитировать Сообщить модератору
 Re: группировка  [new]
sskk
Guest
declare @t table (i int, d datetime, t varchar(10))
insert into @t
values(10,'20120101','a'),
(20,'20120501','b'),
(30,'20120601','b'),
(15,'20120708','a')


select sum(s_a) s_a,sum(s_b) s_b,min(d)d,sum(stat) stat
from(
	select i,
	case t when 'a' then i else 0 end s_a,
	case t when 'b' then i else 0 end s_b,
	case when t='b' and i >= 20 then d else '20501231' end d,
	t,
	case when row_number()over(partition by case when t='b' and i >= 20 then 1 else 0 end order by d) =1 and t='b' then i else null end stat
	from @t tb
)z
1 окт 12, 23:12    [13252932]     Ответить | Цитировать Сообщить модератору
 Re: группировка  [new]
sskk
Guest
может вроде этого?
1 окт 12, 23:13    [13252940]     Ответить | Цитировать Сообщить модератору
 Re: группировка  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
Зачем? Зачем делать тучу вычислений для каждой строки если надо под-запросом получить одну.
mindate (или MinID) уже известен/получен.
2 окт 12, 02:18    [13253301]     Ответить | Цитировать Сообщить модератору
 Re: группировка  [new]
init.ora
Member

Откуда: гетто
Сообщений: 317
я согласен, что незачем.
но если топикстартер попросил без подзапросов..
пусть сам решает(:
2 окт 12, 10:09    [13253894]     Ответить | Цитировать Сообщить модератору
 Re: группировка  [new]
Добрый Э - Эх
Guest
bacalavr
неужели подзапрос?
Как вариант - почитать тут :)
2 окт 12, 10:24    [13253971]     Ответить | Цитировать Сообщить модератору
 Re: группировка  [new]
bacalavr
Member

Откуда:
Сообщений: 311
всем спасибо, будем пробовать варианты
2 окт 12, 11:18    [13254278]     Ответить | Цитировать Сообщить модератору
 Re: группировка  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
Добрый Э - Эх
Как вариант - почитать тут :)
Аля Included поля для агрегаток.

На самом деле часто краевые вещи типа Max/Min делаются "скрытыми под-запросами", посмотрите планы.
Конечно оптимизатор скорее CASE не обработает, но "продвинутый" может подсчитать что если объём инфы при отдельном под-запросе будет меньше, то так и сделает.[MemSize(<CASE WHEN Query>) < Diff(<AggQuery> without CASE)]

Всё дело в сахаре, а не оптимизации. В основном.
Оконные функции хорошо, но они слабые, именно для формализации.
Т.к. тут нужны наборы, то это должно быть что-то во FROM, хотя есть в некоторых SQL-ях как такие скалярки (те что в SELECT пишутся) которые выводят наборы (sets) - но это изврат.
Но лучше что-то отдельно, типа после GROUP BY какой-то FOR, аля:
SELECT	 sum(T.i)
	,M.id
	,M.d
	,M.i
FROM	@t	AS T
GROUP BY t
FOR	Max(d)	AS M WHEN T.i >= 20
А то так не очень:
SELECT	 sum(T.i)
	,Max(T.d)
	,For(Max(T.d))Get(T.id)
	,For(Max(T.d))Get(T.i)
FROM	@t	AS T
GROUP BY t
2 окт 12, 11:20    [13254285]     Ответить | Цитировать Сообщить модератору
 Re: группировка  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
Забыл упомянуть. Никто не против своих агрегатках на CLR.
2 окт 12, 11:24    [13254319]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить