Я использовал GROUP BY
для всех типов агрегированных запросов за эти годы. Недавно я переработал код, который использует PARTITION BY
для выполнения агрегаций. Прочитав всю документацию, которую я могу найти о PARTITION BY
, она очень похожа на GROUP BY
, может быть, с добавлением немного дополнительной функциональности? Являются ли они двумя версиями одной и той же общей функциональности или они полностью отличаются друг от друга?
SQL Server: разница между PARTITION BY и GROUP BY
Ответ 1
Они используются в разных местах. group by
изменяет весь запрос, например:
select customerId, count(*) as orderCount
from Orders
group by customerId
Но row_number
partition by
просто работает с оконной функцией, например row_number
:
select row_number() over (partition by customerId order by orderId)
as OrderNumberForThisCustomer
from Orders
group by
обычно уменьшает количество возвращаемых строк, свернув их и вычислив средние или суммы для каждой строки. partition by
не влияет на количество возвращаемых строк, но меняет способ вычисления результата оконной функции.
Ответ 2
Мы можем взять простой пример.
Рассмотрим таблицу с именем 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 можно использовать в операторе SELECT для сбора данных по нескольким записям и группировки результатов по одному или нескольким столбцам.
В более простых словах оператор GROUP BY используется вместе с агрегатными функциями для группировки результирующего набора по одному или нескольким столбцам.
Синтаксис:
SELECT expression1, expression2, ... expression_n,
aggregate_function (aggregate_expression)
FROM tables
WHERE conditions
GROUP BY expression1, expression2, ... expression_n;
Мы можем применить GROUP BY
в нашей таблице:
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
обычно уменьшает количество строк, возвращаемых путем свертывания их и вычисленияSum()
для каждой строки.
PARTITION BY
Прежде чем перейти к PARTITION BY, давайте посмотрим на предложение OVER
:
Согласно определению MSDN:
Предложение OVER определяет окно или заданный пользователем набор строк в наборе результатов запроса. Затем оконная функция вычисляет значение для каждой строки в окне. Вы можете использовать предложение OVER с функциями для вычисления агрегированных значений, таких как скользящие средние, кумулятивные агрегаты, промежуточные итоги или максимальный N для каждой группы результатов.
PARTITION BY не уменьшит количество возвращаемых строк.
Мы можем применить 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.
Ответ 3
partition by
фактически не сворачивает данные. Это позволяет вам reset что-то на каждой группе. Например, вы можете получить порядковый столбец внутри группы путем разбиения на поле группировки и использования rownum()
над строками внутри этой группы. Это дает вам то, что ведет себя немного как столбец идентификатора, который сбрасывается в начале каждой группы.
Ответ 4
РАЗДЕЛЕНИЕ Разделение результирующего набора на разделы. Функция окна применяется к каждому разделу отдельно, и вычисление перезапускается для каждого раздела.
Найдено по этой ссылке: раздел OVER
Ответ 5
Он предоставляет свернутые данные без свертывания
то есть. Предположим, я хочу вернуть относительное положение области продаж
Используя PARTITION BY, я могу вернуть сумму продаж для данного региона и сумму MAX во всех регионах продаж в той же строке.
Это означает, что вы будете повторять данные, но это может подойти конечному потребителю в том смысле, что данные были агрегированы, но данные не были потеряны - как это было бы с GROUP BY.
Ответ 6
PARTITION BY
является аналитическим, а GROUP BY
является агрегатом. Чтобы использовать PARTITION BY
, вы должны содержать его с предложением OVER.
Ответ 7
По моему мнению, раздел By почти идентичен группе By, но со следующими отличиями:
Эта группа фактически группирует результирующий набор, возвращающий одну строку для каждой группы, что в результате приводит к тому, что в SQL Server разрешено только в агрегатных функциях или столбцах SELECT, которые являются частью предложения group by (в этом случае SQL Server может гарантировать, что для каждой группы есть уникальные результаты).
Рассмотрим, например, MySQL, который позволяет иметь в столбцах списка SELECT, которые не определены в предложении Group By, и в этом случае одна строка все еще возвращается на группу, однако, если столбец не имеет уникальных результатов, тогда не гарантирует, какой будет выход!
Но с Partition By, хотя результаты функции идентичны результатам агрегатной функции с Group By, вы все равно получаете нормальный набор результатов, а это означает, что каждый получает одну строку в каждой строке, а не одна строка на группу, и из-за этого могут быть столбцы, которые не уникальны для каждой группы в списке SELECT.
Итак, в качестве сводки, Group By будет лучше всего, когда требуется вывод одной строки для каждой группы, а Partition By будет лучше всего, когда нужны все строки, но все же хочет, чтобы агрегатная функция была основана на группе.
Конечно, могут быть проблемы с производительностью, см. http://social.msdn.microsoft.com/Forums/ms-MY/transactsql/thread/0b20c2b5-1607-40bc-b7a7-0c60a2a55fba.
Ответ 8
Предположим, что у нас есть 14 записей столбца name
в таблице
in group by
select name,count(*) as totalcount from person where name='Please fill out' group BY name;
он даст счет в одной строке i.e 14
но в partition by
select row_number() over (partition by name) as total from person where name = 'Please fill out';
он будет 14 строк увеличения количества
Ответ 9
Небольшое наблюдение. Механизм автоматизации для динамического генерации SQL с использованием "раздела" намного проще реализовать в отношении "group by". В случае "group by", мы должны позаботиться о содержании столбца "select".
Извините за мой английский.
Ответ 10
У него действительно разные сценарии использования. Когда вы используете GROUP BY, вы объединяете некоторые записи для одинаковых столбцов, и вы получаете совокупность результирующего набора.
Однако, когда вы используете PARTITION BY, ваш набор результатов такой же, но у вас просто агрегирование по оконным функциям, и вы не объединяете записи, у вас все равно будет такое же количество записей.
Вот полезная статья, объясняющая разницу: http://alevryustemov.com/sql/sql-partition-by/
Ответ 11
При использовании GROUP BY
результирующие строки обычно будут меньше входящих строк.
Но когда вы используете PARTITION BY
, результирующий счетчик строк должен быть таким же, как и входящий.
Ответ 12
Partition By является пассивным, но Group by Is Active означает
выходные строки изменяются, когда применяется группировка по, в основном уменьшается, следовательно, активна, в то время как в разделе секция остается той же самой, что делает ее пассивной, а также, поскольку их нет в выходных строках в секции, следовательно, агрегация отличается от группы по.
Ответ 13
-- 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