Oracle “Partition por” Palavra-chave
-
05-09-2019 - |
Pergunta
Por favor alguém pode explicar o que a palavra-chave partition by
faz e dar um exemplo simples dele em ação, bem como por que alguém iria querer usá-lo? Eu tenho uma consulta SQL escrito por outra pessoa e eu estou tentando descobrir o que ele faz.
Um exemplo de partição por:
SELECT empno, deptno, COUNT(*)
OVER (PARTITION BY deptno) DEPT_COUNT
FROM emp
Os exemplos que eu vi online parecem um pouco demasiado em profundidade.
Solução
A cláusula PARTITION BY
define o intervalo de registros que serão utilizados para cada "grupo" dentro da cláusula OVER
.
No seu exemplo SQL, DEPT_COUNT
irá retornar o número de empregados dentro desse departamento para cada registro de empregado. (É como se você está-de nomalising tabela emp
;. Você ainda retornar cada registro na tabela de 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
Se houvesse outra coluna (por exemplo, state
), então você pode contar quantos departamentos nesse Estado.
É como obter os resultados de um GROUP BY
(SUM
, AVG
, etc.) sem a agregar o conjunto de resultados (ou seja, a remoção de registros correspondentes).
É útil quando você usa as funções LAST OVER
ou MIN OVER
para obter, por exemplo, o salário mais baixo e mais alto no departamento e, em seguida, usar isso em um cálculo contra este salário registros sem a sub seleccionar , que é muito mais rápido.
Leia o artigo ligado AskTom para mais detalhes.
Outras dicas
O conceito é muito bem explicado pela resposta aceita, mas acho que o mais exemplo vê-se, o melhor que ele afunda dentro Aqui está um exemplo incremental:.
1) diz chefe "me número de itens que temos em estoque agrupados por marca"
Você diz : "nenhum problema"
SELECT
BRAND
,COUNT(ITEM_ID)
FROM
ITEMS
GROUP BY
BRAND;
Resultado:
+--------------+---------------+
| Brand | Count |
+--------------+---------------+
| H&M | 50 |
+--------------+---------------+
| Hugo Boss | 100 |
+--------------+---------------+
| No brand | 22 |
+--------------+---------------+
2) O chefe diz "Agora me uma lista de todos os itens, com a sua marca e número de itens que a respectiva marca tem"
Você pode tentar:
SELECT
ITEM_NR
,BRAND
,COUNT(ITEM_ID)
FROM
ITEMS
GROUP BY
BRAND;
Mas você tem:
ORA-00979: not a GROUP BY expression
Este é o lugar onde o OVER (PARTITION BY BRAND)
vem em:
SELECT
ITEM_NR
,BRAND
,COUNT(ITEM_ID) OVER (PARTITION BY BRAND)
FROM
ITEMS;
meios whic:
-
COUNT(ITEM_ID)
- obter o número de itens -
OVER
- sobre o conjunto de linhas -
(PARTITION BY BRAND)
- que têm a mesma marca
E o resultado é:
+--------------+---------------+----------+
| 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 |
+--------------+---------------+----------+
etc ...
É a extensão SQL chamada analytics. O "over" na instrução SELECT diz oráculo que a função é uma função analítica, não um grupo por função. A vantagem de usar analytics é que você pode ganhar somas, contagens, e muito mais com apenas uma passagem através dos dados em vez de loop através dos dados com sub seleciona ou pior, PL / SQL.
Ele parece confuso no início, mas isso vai ser uma segunda natureza rapidamente. Ninguém explica isso melhor, em seguida, Tom Kyte. Assim, o link acima é grande.
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
Aqui nós estamos começando a contagem para a respectiva deptno. Quanto deptno 10 temos 4 registros em resultados semelhantes tabela emp para deptno 20 e 30 também.
a palavra-chave partição sobre é como se nós estamos dividindo os dados por client_id criação de um subconjunto de cada ID de cliente
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;
Essa consulta retornará o número de operações realizado pela client_id