Ключевое слово Oracle "Partition By" - PullRequest
229 голосов
/ 18 февраля 2009

Может кто-нибудь объяснить, что делает ключевое слово partition by, и дать простой пример его в действии, а также зачем его использовать? У меня есть SQL-запрос, написанный кем-то другим, и я пытаюсь выяснить, что он делает.

Пример разбиения по:

SELECT empno, deptno, COUNT(*) 
OVER (PARTITION BY deptno) DEPT_COUNT
FROM emp

Примеры, которые я видел в Интернете, кажутся слишком глубокими.

Ответы [ 5 ]

238 голосов
/ 18 февраля 2009

Предложение PARTITION BY устанавливает диапазон записей, которые будут использоваться для каждой "ГРУППЫ" в предложении OVER.

В вашем примере SQL, DEPT_COUNT будет возвращать количество сотрудников в этом отделе для каждой записи сотрудника. (Это похоже на то, как если бы вы отменяли имя таблицы emp; вы по-прежнему возвращаете каждую запись в таблице emp.)

emp_no  dept_no  DEPT_COUNT
1       10       3
2       10       3
3       10       3 <- three because there are three "dept_no = 10" records
4       20       2
5       20       2 <- two because there are two "dept_no = 20" records

Если был другой столбец (например, state), то вы могли бы подсчитать, сколько департаментов в этом штате.

Это похоже на получение результатов GROUP BY (SUM, AVG и т. Д.) Без агрегирования набора результатов (т. Е. Удаления соответствующих записей).

Это полезно, когда вы используете функции LAST OVER или MIN OVER для получения, например, самой низкой и самой высокой зарплаты в отделе, а затем используете ее при расчете по этой записи зарплаты без суб-выбор, который намного быстрее.

Прочитайте связанную статью AskTom для получения более подробной информации.

127 голосов
/ 24 июня 2016

Концепция очень хорошо объяснена принятым ответом, но я обнаружил, что чем больше примеров видно, тем лучше он погружается. Вот пример с приращением:

1) Босс говорит"достаньте мне количество товаров на складе, сгруппированных по маркам"

Вы говорите : "нет проблем"

SELECT 
      BRAND
      ,COUNT(ITEM_ID) 
FROM 
      ITEMS
GROUP BY 
      BRAND;

Результат:

+--------------+---------------+
|  Brand       |   Count       | 
+--------------+---------------+
| H&M          |     50        |
+--------------+---------------+
| Hugo Boss    |     100       |
+--------------+---------------+
| No brand     |     22        |
+--------------+---------------+

2) Босс говорит «Теперь возьми мне список всех предметов с указанием их бренда И количества предметов, которые имеет соответствующий бренд»

Вы можете попробовать:

 SELECT 
      ITEM_NR
      ,BRAND
      ,COUNT(ITEM_ID) 
 FROM 
      ITEMS
 GROUP BY 
      BRAND;

Но вы получите:

ORA-00979: not a GROUP BY expression 

Вот где OVER (PARTITION BY BRAND) входит:

 SELECT 
      ITEM_NR
      ,BRAND
      ,COUNT(ITEM_ID) OVER (PARTITION BY BRAND) 
 FROM 
      ITEMS;

Что означает:

  • COUNT(ITEM_ID) - получить количество предметов
  • OVER - над множеством строк
  • (PARTITION BY BRAND) - с одинаковой маркой

И результат:

+--------------+---------------+----------+
|  Items       |  Brand        | Count()  |
+--------------+---------------+----------+
|  Item 1      |  Hugo Boss    |   100    | 
+--------------+---------------+----------+
|  Item 2      |  Hugo Boss    |   100    | 
+--------------+---------------+----------+
|  Item 3      |  No brand     |   22     | 
+--------------+---------------+----------+
|  Item 4      |  No brand     |   22     | 
+--------------+---------------+----------+
|  Item 5      |  H&M          |   50     | 
+--------------+---------------+----------+

и т.д ...

26 голосов
/ 27 февраля 2009

Это расширение SQL, называемое аналитикой. «Over» в операторе select говорит оракулу, что функция является аналитической функцией, а не группой по функции. Преимущество использования аналитики заключается в том, что вы можете собирать суммы, числа и многое другое всего за один проход данных, а не циклически перебирать данные с подвыборками или, что еще хуже, PL / SQL.

Поначалу это выглядит странно, но это быстро станет второй натурой. Никто не объясняет это лучше, чем Том Кайт. Так что ссылка выше отличная.

Конечно, чтение документации является обязательным.

10 голосов
/ 25 августа 2009
EMPNO     DEPTNO DEPT_COUNT

 7839         10          4
 5555         10          4
 7934         10          4
 7782         10          4 --- 4 records in table for dept 10
 7902         20          4
 7566         20          4
 7876         20          4
 7369         20          4 --- 4 records in table for dept 20
 7900         30          6
 7844         30          6
 7654         30          6
 7521         30          6
 7499         30          6
 7698         30          6 --- 6 records in table for dept 30

Здесь мы получаем подсчет за соответствующий отдел. Что касается 10, у нас есть 4 записи в таблице emp, аналогичные результаты для 20 и 30 также.

2 голосов
/ 28 октября 2016

ключевое слово over partition выглядит так, как будто мы разделяем данные по client_id создание подмножества каждого идентификатора клиента

select client_id, operation_date,
       row_number() count(*) over (partition by client_id order by client_id ) as operationctrbyclient
from client_operations e
order by e.client_id;

этот запрос вернет количество операций, выполненных client_id

...