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

Откуда:
Сообщений: 3274
Столкнулся с интересным поведением GROUP BY - раньше такого не замечал, хотя фича, похоже, не новая:

declare @Sales table (
	Id int identity(1,1) primary key,
	CustomerId int not null,
	SaleDate datetime not null,
	Amount money not null
);

insert into @Sales (CustomerId, SaleDate, Amount)
values
	(1, '20100506 12:00', 280),
	(3, '20100607 12:00', 150);


select max(s.SaleDate) as [LastDate], sum(s.Amount) as [TotalAmount], count(*) as [Count]
from @Sales s
where s.CustomerId = 2;

select max(s.SaleDate) as [LastDate], sum(s.Amount) as [TotalAmount], count(*) as [Count]
from @Sales s
where s.CustomerId = 2
group by s.CustomerId;

Специально перечитал раздел справки по group by, но не нашел никаких упоминаний подобного поведения. Кто-нибудь в курсе, почему оно именно так работает?
10 окт 14, 18:30    [16688880]     Ответить | Цитировать Сообщить модератору
 Re: GROUP BY работает как фильтр  [new]
iap
Member

Откуда: Москва
Сообщений: 47000
http://msdn.microsoft.com/ru-ru/library/ms177673(v=sql.100).aspx
Строки, которые не соответствуют условиям в предложении WHERE,
удаляются до выполнения любых операций группирования.
10 окт 14, 18:38    [16688916]     Ответить | Цитировать Сообщить модератору
 Re: GROUP BY работает как фильтр  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37056
Все логично.

Группировка пустого набора всегда была пустым набором.
Но при этом на пустом наборе можно считать агрегаты по всему набору.
10 окт 14, 18:40    [16688925]     Ответить | Цитировать Сообщить модератору
 Re: GROUP BY работает как фильтр  [new]
a_voronin
Member

Откуда: Москва
Сообщений: 4804
У вас тут два запроса эквивалентных, которые возвращают один и тот же результат. Что за " GROUP BY работает как фильтр"?
10 окт 14, 18:44    [16688948]     Ответить | Цитировать Сообщить модератору
 Re: GROUP BY работает как фильтр  [new]
Glory
Member

Откуда:
Сообщений: 104760
a_voronin
У вас тут два запроса эквивалентных, которые возвращают один и тот же результат.

Разные результаты - в одном есть запись, а в другом нет
10 окт 14, 18:45    [16688952]     Ответить | Цитировать Сообщить модератору
 Re: GROUP BY работает как фильтр  [new]
tarrus
Member

Откуда: Bergen
Сообщений: 831
a_voronin
У вас тут два запроса эквивалентных, которые возвращают один и тот же результат. Что за " GROUP BY работает как фильтр"?


Совсем не эквивалентных. Результат разный.
10 окт 14, 18:46    [16688955]     Ответить | Цитировать Сообщить модератору
 Re: GROUP BY работает как фильтр  [new]
Ennor Tiegael
Member

Откуда:
Сообщений: 3274
iap, Гавриленко Сергей Алексеевич,

Вы пробовали выполнять код из примера?
10 окт 14, 18:55    [16688988]     Ответить | Цитировать Сообщить модератору
 Re: GROUP BY работает как фильтр  [new]
Glory
Member

Откуда:
Сообщений: 104760
Ennor Tiegael
Вы пробовали выполнять код из примера?

Пробовали
Все просто
group by начнет вычисление агрегатов только при наличии групп
Т.е. нет групп - нет вызова агрегатов, нет вызова агрегатов - нет реузльтата

Сообщение было отредактировано: 10 окт 14, 18:58
10 окт 14, 18:57    [16688995]     Ответить | Цитировать Сообщить модератору
 Re: GROUP BY работает как фильтр  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37056
Ennor Tiegael
iap, Гавриленко Сергей Алексеевич,

Вы пробовали выполнять код из примера?
Пробовали. А вы пробовали понять, что я ответил?
10 окт 14, 19:15    [16689081]     Ответить | Цитировать Сообщить модератору
 Re: GROUP BY работает как фильтр  [new]
Shakill
Member

Откуда: мск
Сообщений: 1880
кстати, этот прием может пригодиться при выборке единственного значения из набора, когда надо сбрасывать переменную в NULL, если ничего не нашлось.

declare @objname sysname = 'oldname'

select @objname = max(sy.name)
from sys.objects as sy
where sy.object_id = 500000

select @objname

хотя можно и просто set @objname = NULL перед выборкой :)
10 окт 14, 19:32    [16689148]     Ответить | Цитировать Сообщить модератору
 Re: GROUP BY работает как фильтр  [new]
Ennor Tiegael
Member

Откуда:
Сообщений: 3274
Гавриленко Сергей Алексеевич,

Разумеется, до сих пор пытаюсь. Кажется, даже начало получаться. Спасибо.
10 окт 14, 19:56    [16689215]     Ответить | Цитировать Сообщить модератору
 Re: GROUP BY работает как фильтр  [new]
a_voronin
Member

Откуда: Москва
Сообщений: 4804
Ennor Tiegael
Гавриленко Сергей Алексеевич,

Разумеется, до сих пор пытаюсь. Кажется, даже начало получаться. Спасибо.


Если по делу, что может вам надо написать

SELECT ....
FROM Customers c
LEFT JOIN Sales s ON s.CustomerId = c.Customer_id 
GROUP BY c.Customer_id 
10 окт 14, 20:11    [16689261]     Ответить | Цитировать Сообщить модератору
 Re: GROUP BY работает как фильтр  [new]
iap
Member

Откуда: Москва
Сообщений: 47000
Ennor Tiegael
iap, Гавриленко Сергей Алексеевич,

Вы пробовали выполнять код из примера?
Да!
10 окт 14, 20:31    [16689349]     Ответить | Цитировать Сообщить модератору
 Re: GROUP BY работает как фильтр  [new]
iap
Member

Откуда: Москва
Сообщений: 47000
iap
Ennor Tiegael
iap, Гавриленко Сергей Алексеевич,

Вы пробовали выполнять код из примера?
Да!
Пытался найти что-то подходящее в документации.
Помню, на форуме были обсуждения в какой-то теме применительно к COUNT(*).
Если GROUP BY есть, то для пустого DataSet не возвращается ни одной строки,
а если нет, то возвращается 0.
Но я чего-то эту тему быстро не нашёл.
10 окт 14, 20:35    [16689366]     Ответить | Цитировать Сообщить модератору
 Re: GROUP BY работает как фильтр  [new]
invm
Member

Откуда: Москва
Сообщений: 9400
Это называется "скалярные агрегаты"
http://blogs.msdn.com/b/craigfr/archive/2006/09/06/743116.aspx
In this post, I’m going to focus on “scalar aggregates.” Scalar aggregates are queries with aggregate functions in the select list and no GROUP BY clause. Scalar aggregates always return a single row.
10 окт 14, 22:16    [16689795]     Ответить | Цитировать Сообщить модератору
 Re: GROUP BY работает как фильтр  [new]
Ennor Tiegael
Member

Откуда:
Сообщений: 3274
invm,

То, что агрегаты возвращают одну строку, как раз ожидаемо. Неожиданной была ситуация, когда они перестают это делать. И вот об этом у Фридмана ни слова - он рассматривает более низкий, физический, уровень, а это в данном случае как раз иррелевантно (ибо неважно, будет это Stream или Hash Aggregate - результат запроса будет одинаковый).

Может, конечно, это всем настолько очевидно, что никто даже не видит смысла в упоминании такой возможности, и это только я один такой темный. Но, имхо, как минимум в справке стоило о такой возможности упомянуть. Простейший пример - апдейт таблицы агрегатом, получаемым из APPLY. В зависимости от формулировки, CROSS может внезапно превратиться в OUTER и наоборот.
11 окт 14, 10:07    [16690419]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить