Oracle « Partition par » Mot-clé
-
05-09-2019 - |
Question
Quelqu'un peut-il s'il vous plaît expliquer ce que le mot-clé partition by
fait et donner un exemple simple en action, ainsi que la raison pour laquelle on voudrait l'utiliser? J'ai une requête SQL écrite par quelqu'un d'autre et je suis en train de comprendre ce qu'il fait.
Un exemple de partition par:
SELECT empno, deptno, COUNT(*)
OVER (PARTITION BY deptno) DEPT_COUNT
FROM emp
Les exemples que je l'ai vu en ligne semblent un peu trop en profondeur.
La solution
La clause PARTITION BY
définit la plage d'enregistrements qui seront utilisés pour chaque « GROUP » dans la clause OVER
.
Dans votre exemple SQL, DEPT_COUNT
retourne le nombre d'employés au sein de ce département pour chaque enregistrement des employés. (Il est comme si vous de-nomalising la table emp
;. Vous revenez toujours tous les enregistrements de la table 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
S'il y avait une autre colonne (par exemple, state
), alors vous pouvez compter combien de ministères dans cet Etat.
Il est comme obtenir les résultats d'une GROUP BY
(SUM
, AVG
, etc.) sans l'agrégation de l'ensemble des résultats (à savoir la suppression des enregistrements correspondant).
Il est utile lorsque vous utilisez les fonctions de LAST OVER
ou MIN OVER
pour obtenir, par exemple, le plus bas et le plus haut salaire dans le département et utiliser alors que dans un calcul contre ce RECORDS salaire sans un sous sélectionnez , ce qui est beaucoup plus rapide.
Lire le lien AskTom article pour plus de détails.
Autres conseils
Le concept est très bien expliqué par la réponse acceptée, mais je trouve que plus on voit par exemple, plus il coule dans Voici un exemple supplémentaire.
1) Patron dit "me obtenir le nombre d'articles que nous avons en stock regroupés par marque"
Vous dites : "pas de problème"
SELECT
BRAND
,COUNT(ITEM_ID)
FROM
ITEMS
GROUP BY
BRAND;
Résultat:
+--------------+---------------+
| Brand | Count |
+--------------+---------------+
| H&M | 50 |
+--------------+---------------+
| Hugo Boss | 100 |
+--------------+---------------+
| No brand | 22 |
+--------------+---------------+
2) Le patron dit « Maintenant me faire une liste de tous les articles, avec leur marque et le nombre d'articles que la marque respective a »
Vous pouvez essayer:
SELECT
ITEM_NR
,BRAND
,COUNT(ITEM_ID)
FROM
ITEMS
GROUP BY
BRAND;
Mais vous obtenez:
ORA-00979: not a GROUP BY expression
C'est là que vient OVER (PARTITION BY BRAND)
:
SELECT
ITEM_NR
,BRAND
,COUNT(ITEM_ID) OVER (PARTITION BY BRAND)
FROM
ITEMS;
Quelle st signifie:
-
COUNT(ITEM_ID)
- obtenir le nombre d'éléments -
OVER
- Au cours de l'ensemble de lignes -
(PARTITION BY BRAND)
- qui ont la même marque
Et le résultat est:
+--------------+---------------+----------+
| 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 ...
Il est l'extension SQL appelée analyse. Le « plus » dans l'instruction select indique oracle que la fonction est une fonction d'analyse, pas un groupe par fonction. L'avantage d'utiliser l'analyse est que vous pouvez gagner des sommes, compte, et beaucoup plus avec juste un passage à travers des données au lieu de boucle à travers les données avec les sous ou pire sélectionne, PL / SQL.
Il ne semble déroutant au début, mais ce sera une seconde nature rapidement. Personne ne l'explique mieux que Tom Kyte. Donc le lien ci-dessus est 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
Ici, nous obtenons le nombre de deptno respectifs. En ce qui concerne deptno 10, nous avons 4 enregistrements dans la table emp résultats similaires pour deptno 20 et 30 également.
le mot-clé de partition est plus comme si nous le partitionnement des données par client_id la création d'un sous-ensemble de chaque identifiant client
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;
cette requête renverra le nombre d'opérations effectuées par le client_id