2009-02-18 1 views
192

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

Пример раздела по:

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

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

ответ

209

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

В вашем примере SQL, DEPT_COUNT вернет число сотрудников в этом отделе для каждой записи сотрудника. (Это как если бы ваш де-nomalising в 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 функции, чтобы получить, например, самый низкий и самый высокий оклад в отделе, а затем использовать его в calulation против этой записи зарплаты без саб выбора, который намного Быстрее.

Прочтите дополнительную информацию о AskTom article.

+1

2-е объяснение линия @ код, если он скажет «два, потому что есть две записи dept_no = 20». Любой может редактировать? :) –

+1

Камило, я исправил пример. Спасибо. – Guy

+1

thanx для AskTom ссылка –

24

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

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

Конечно, чтение documentation является обязательным.

9
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 

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

+10

Не стоит ссылаться на вопрос о том, как работает PARTITION. Только один пример вывода не полностью отвечает на вопрос. –

76

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

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; 

Whic означает:

  • 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  | 
+--------------+---------------+----------+ 

и т.д. ...

+0

save me alottt of time – dadan

+1

Очень хорошее объяснение. – danizmax

+0

Если я хочу получить один результат для каждой группы. Как я его получу? –

1

чрезмерное разделение ключевых слов, как если бы мы секционирования данные по 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