it-swarm.com.ru

SQL Server: разница между PARTITION BY и GROUP BY

Я использовал GROUP BY для всех типов совокупных запросов на протяжении многих лет. Недавно я провел обратный инжиниринг кода, который использует PARTITION BY для выполнения агрегации. Читая всю документацию, которую я могу найти о PARTITION BY, она звучит очень похоже на GROUP BY, может быть, с добавлением немного дополнительной функциональности? Это две версии одного и того же общего функционала или они что-то совершенно другое?

291
Mike Mooney

Они используются в разных местах. group by изменяет весь запрос, например:

select customerId, count(*) as orderCount
from Orders
group by customerId

Но partition by просто работает с оконной функцией , как row_number:

select row_number() over (partition by customerId order by orderId)
    as OrderNumberForThisCustomer
from Orders

group by обычно уменьшает количество возвращаемых строк, сворачивая их и вычисляя средние или суммы для каждой строки. partition by не влияет на количество возвращаемых строк, но меняет способ вычисления результата оконной функции.

353
Andomar

Мы можем взять простой пример 

у нас есть таблица с именем TableA со следующими значениями.

id  firstname                   lastname                    Mark
-------------------------------------------------------------------
1   arun                        prasanth                    40
2   ann                         antony                      45
3   sruthy                      abc                         41
6   new                         abc                         47
1   arun                        prasanth                    45
1   arun                        prasanth                    49
2   ann                         antony                      49

Группа по  

Предложение SQL GROUP BY можно использовать в операторе SELECT для сбора данные по нескольким записям и сгруппировать результаты по одной или нескольким колонны.

В более простых словах оператор GROUP BY используется вместе с агрегатные функции для группировки результирующего набора по одному или нескольким колонны.

синтаксис:

SELECT expression1, expression2, ... expression_n, 
       aggregate_function (aggregate_expression)
FROM tables
WHERE conditions
GROUP BY expression1, expression2, ... expression_n;

Мы можем применить GroupBy в нашей таблице 

select SUM(Mark)marksum,firstname from TableA
group by id,firstName

Результаты :

marksum  firstname
----------------
94      ann                      
134     arun                     
47      new                      
41      sruthy   

В нашей реальной таблице у нас есть 7 строк, и когда мы применяем group by id, сервер группирует результаты на основе id

Простыми словами 

здесь group by обычно уменьшает количество строк, возвращаемых путем прокрутки их и вычисление суммы для каждой строки.

разделить на

прежде чем перейти к разделу 

давайте посмотрим на предложение OVER 

Согласно определению MSDN  

Предложение OVER определяет окно или заданный пользователем набор строк в набор результатов запроса. Затем оконная функция вычисляет значение для каждой строки в окне Вы можете использовать предложение OVER с функциями для вычисления агрегированные значения, такие как скользящие средние, совокупные агрегаты, промежуточные итоги, или N лучших результатов в группе.

partition by не уменьшит количество возвращаемых строк

мы можем применить раздел в нашем примере таблицы

select SUM(Mark) OVER (PARTITION BY id) AS marksum, firstname from TableA

результат:

marksum firstname 
-------------------
134     arun                     
134     arun                     
134     arun                     
94      ann                      
94      ann                      
41      sruthy                   
47      new  

посмотрите на результаты, которые будут разделены на строки, и в результате все строки будут не похожи на group by. 

192
Arunprasanth K V

partition by на самом деле не сворачивает данные. Это позволяет вам сбросить что-то для каждой группы. Например, вы можете получить порядковый столбец в группе, разделив поле группировки и используя rownum() над строками в этой группе. Это дает вам нечто похожее на столбец идентификаторов, который сбрасывается в начале каждой группы.

48
ConcernedOfTunbridgeWells

PARTITION BY Делит результирующий набор на разделы. Функция окна применяется к каждому разделу отдельно, и вычисление перезапускается для каждого раздела.

Найдено по этой ссылке: OVER Clause

35
Will Marcouiller

Предоставляет свернутые данные без свертывания

т.е. я хочу вернуть относительную позицию региона продаж

Используя PARTITION BY, я могу вернуть сумму продаж для данного региона и максимальную сумму по всем регионам продаж в одной строке.

Это означает, что у вас будут повторяющиеся данные, но это может подойти конечному потребителю в том смысле, что данные были агрегированы, но данные не были потеряны - как в случае с GROUP BY.

27
adolf garlic

PARTITION BY является аналитическим, а GROUP BY является совокупным. Чтобы использовать PARTITION BY, вы должны содержать его с условием OVER .

23
OMG Ponies

Насколько я понимаю, раздел By почти идентичен группе By, но со следующими отличиями:

Эта группа фактически группирует результирующий набор, возвращая по одной строке на группу, что приводит к тому, что SQL Server допускает только агрегированные функции или столбцы списка SELECT, которые являются частью предложения group by (в этом случае SQL Server может гарантировать, что существуют уникальные результаты для каждой группы).

Рассмотрим, например, MySQL, который позволяет иметь в списке SELECT столбцы, которые не определены в предложении Group By, и в этом случае по-прежнему возвращается одна строка на группу, однако, если столбец не имеет уникальных результатов, гарантия не гарантируется. какой будет выход!

Но с Partition By, хотя результаты функции идентичны результатам агрегатной функции с Group By, вы все равно получаете нормальный набор результатов, что означает, что один получает одну строку на базовую строку, а не одну строку на group, и из-за этого в списке SELECT могут быть столбцы, которые не являются уникальными для каждой группы.

Таким образом, в качестве резюме, Group By будет лучше, когда требуется вывод по одной строке на группу, а Partition By будет лучше, когда нужны все строки, но все же требуется агрегатная функция, основанная на группе. 

Конечно, также могут быть проблемы с производительностью, см. http://social.msdn.Microsoft.com/Forums/ms-MY/transactsql/thread/0b20c2b5-1607-40bc-b7a7-0c60a2a55fba .

20
yoel halb

Предположим, у нас есть 14 записей столбца name в таблице

в group by

select name,count(*) as totalcount from person where name='Please fill out' group BY name;

это даст счет в одной строке, т.е. 14

но в partition by

select row_number() over (partition by name) as total from person where name = 'Please fill out';

это будет 14 рядов увеличения количества

0
Ambrish Rajput

Небольшое наблюдение. Механизм автоматизации для динамической генерации SQL с использованием «разбиения по» гораздо проще реализовать по отношению к «группированию по». В случае «group by», мы должны позаботиться о содержимом столбца «select».

Извините за мой английский.

0
user1785960