Я использую GROUP BY
для всех типов совокупных запросов за эти годы. Недавно я переработал код, который использует PARTITION BY
для выполнения агрегаций. Прочитав всю документацию, я могу найти около PARTITION BY
, это звучит так же, как GROUP BY
, может быть, с добавлением немного дополнительной функциональности? Являются ли они двумя версиями одной и той же общей функциональности или что-то другое?SQL Server: разница между PARTITION BY и GROUP BY
ответ
Используются в разных местах. group by
изменяет весь запрос, как:
select customerId, count(*) as orderCount
from Orders
group by customerId
Но partition by
просто работает на a window function, как row_number
:
select row_number() over (partition by customerId order by orderId)
as OrderNumberForThisCustomer
from Orders
group by
обычно уменьшает количество строк, возвращаемых путем прокатки их и вычисления средних значений или суммы для каждой строки. partition by
не влияет на количество возвращаемых строк, но изменяет результат вычисления оконной функции.
partition by
фактически не сворачивает данные. Это позволяет вам сбросить что-то на основе каждой группы. Например, вы можете получить порядковый столбец внутри группы путем разбиения на поле группировки и использования rownum()
над строками внутри этой группы. Это дает вам то, что ведет себя немного похоже на столбец идентичности, который сбрасывается в начале каждой группы.
PARTITION BY
является аналитическим, а GROUP BY
является агрегатом. Чтобы использовать PARTITION BY
, вы должны содержать его с OVER clause.
'PARTITION BY является аналитическим', этот простой оператор очень сильно очистился для меня. +1. –
PARTITION BY Разделяет результирующий набор на разделы. Функция окна применяется к каждому разделу отдельно, и вычисление перезапускается для каждого раздела.
Найдено по этой ссылке: OVER Clause
предоставляет свернутые данные без скатывания
т.е. Предположим, я хочу, чтобы вернуть относительную позицию региона продаж
Использование PARTITION BY, I может вернуть сумму продаж для данного региона и сумму MAX во всех регионах продаж в той же строке.
Это означает, что у вас будут повторяющиеся данные, но это может подойти конечному потребителю в том смысле, что данные были агрегированы, но данные не были потеряны - как в случае с GROUP BY.
Самый лучший, самый простой ответ. – tmthyjames
По моему пониманию Partition By почти идентична Group By, но со следующими отличиями:
Эта группа, фактически групп результирующего набора, возвращая одну строку для каждой группы, что приводит поэтому в SQL Server только позволяет в агрегирующие функции SELECT или столбцы, которые являются частью предложения group by (в этом случае SQL Server может гарантировать наличие уникальных результатов для каждой группы).
Рассмотрим, например, MySQL, который позволяет иметь в столбцах списка SELECT, которые не определены в предложении Group By, и в этом случае одна строка все еще возвращается на группу, однако, если столбец не имеет уникальных результатов, тогда нет никакой гарантии, какой будет выход!
Но с Partition By, хотя результаты функции идентичны результатам агрегатной функции с Group By, вы все равно получаете нормальный набор результатов, а это значит, что каждый получает одну строку в каждой строке и не одна строка на группу, и из-за этого могут быть столбцы, которые не уникальны для каждой группы в списке SELECT.
Так как резюме, группа была бы лучше, когда требовалось бы выход из одной строки для каждой группы, а Partition By было бы лучше всего, когда нужно было бы все строки, но все же хочет, чтобы агрегатная функция была основана на группе.
Конечно, могут быть проблемы с производительностью, см. http://social.msdn.microsoft.com/Forums/ms-MY/transactsql/thread/0b20c2b5-1607-40bc-b7a7-0c60a2a55fba.
Мы можем взять простой пример
мы имеем таблицу с именем 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
Group By
SQL-предложения GROUP BY можно использовать в ЗЕЬЕСТ для сбора данные по нескольким записям и сгруппировать результаты по одному или нескольким столбцов.
В более простых словах оператор 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 строк и когда мы применяем группу по id , Сервер сгруппировать результаты, основанные на ID
В простых словах
здесь группе, как правило, уменьшает количество возвращаемых строк путем прокатки их и вычисления Сумма для каждой строки.
раздел по
, прежде чем разделить на
давайте рассмотрим п OVER
Согласно определению MSDN
OVER п определяет окно или заданный пользователем набор строк wi тонкий набор результатов запроса. Затем функция окна вычисляет значение для каждой строки в окне. Вы можете использовать предложение OVER с функциями для вычисления агрегированных значений , таких как скользящие средние, совокупные агрегаты, итоговые итоги или результаты по вершине N на группу.
раздела, не уменьшит количество возвращаемых строк
мы можем применить раздел, в нашем примере таблицы
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
взгляд на результаты будут разбивать строки и результаты, все строки не похожи на группу.
-- BELOW IS A SAMPLE WHICH OUTLINES THE SIMPLE DIFFERENCES
-- READ IT AND THEN EXECUTE IT
-- THERE ARE THREE ROWS OF EACH COLOR INSERTED INTO THE TABLE
-- CREATE A database called testDB
-- use testDB
USE [TestDB]
GO
-- create Paints table
CREATE TABLE [dbo].[Paints](
[Color] [varchar](50) NULL,
[glossLevel] [varchar](50) NULL
) ON [PRIMARY]
GO
-- Populate Table
insert into paints (color, glossLevel)
select 'red', 'eggshell'
union
select 'red', 'glossy'
union
select 'red', 'flat'
union
select 'blue', 'eggshell'
union
select 'blue', 'glossy'
union
select 'blue', 'flat'
union
select 'orange', 'glossy'
union
select 'orange', 'flat'
union
select 'orange', 'eggshell'
union
select 'green', 'eggshell'
union
select 'green', 'glossy'
union
select 'green', 'flat'
union
select 'black', 'eggshell'
union
select 'black', 'glossy'
union
select 'black', 'flat'
union
select 'purple', 'eggshell'
union
select 'purple', 'glossy'
union
select 'purple', 'flat'
union
select 'salmon', 'eggshell'
union
select 'salmon', 'glossy'
union
select 'salmon', 'flat'
/* COMPARE 'GROUP BY' color to 'OVER (PARTITION BY Color)' */
-- GROUP BY Color
-- row quantity defined by group by
-- aggregate (count(*)) defined by group by
select count(*) from paints
group by color
-- OVER (PARTITION BY... Color
-- row quantity defined by main query
-- aggregate defined by OVER-PARTITION BY
select color
, glossLevel
, count(*) OVER (Partition by color)
from paints
/* COMPARE 'GROUP BY' color, glossLevel to 'OVER (PARTITION BY Color, GlossLevel)' */
-- GROUP BY Color, GlossLevel
-- row quantity defined by GROUP BY
-- aggregate (count(*)) defined by GROUP BY
select count(*) from paints
group by color, glossLevel
-- Partition by Color, GlossLevel
-- row quantity defined by main query
-- aggregate (count(*)) defined by OVER-PARTITION BY
select color
, glossLevel
, count(*) OVER (Partition by color, glossLevel)
from paints
Предположим, у нас есть 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 строк увеличения в счете
Небольшое наблюдение. Механизм автоматизации для динамического генерации SQL с использованием «раздела» намного проще реализовать в отношении «group by». В случае «group by» мы должны позаботиться о содержании столбца «select».
Извините за мой английский.
хороший ответ, пожалуйста, напишите образец возвращенных результатов для каждого из них? –
@AshkanMobayenKhiabani вы можете запускать оба запроса против Northwind, которые могут быть установлены или не установлены по умолчанию в зависимости от вашей версии сервера sql. Если нет, вы можете найти его на странице s downloads. –
@AshkanMobayenKhiabani. Ответ Arunprasanth ниже показывает возвращенные результаты, которые могут сэкономить вам время, а не прыгать через дополнительные учебные обручи и время изучать Northwind. – Praxiteles