web-dev-qa-db-fra.com

Mot-clé Oracle "Partition By"

Quelqu'un peut-il expliquer le rôle du mot clé partition by et donner un exemple simple de ce mot en action, ainsi que les raisons pour lesquelles on voudrait l'utiliser? J'ai une requête SQL écrite par quelqu'un d'autre et j'essaie de comprendre ce qu'elle fait.

Un exemple de partition par:

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

Les exemples que j'ai vus en ligne semblent un peu trop approfondis.

238
Alex Beardsley

La clause PARTITION BY définit la plage d'enregistrements à utiliser pour chaque "GROUP" dans la clause OVER.

Dans votre exemple SQL, DEPT_COUNT renverra le nombre d'employés de ce service pour chaque enregistrement d'employé. (C'est comme si vous dé-nomalisiez la table emp; vous retournez 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), vous pouvez compter combien de départements dans cet État.

C'est comme obtenir les résultats d'un GROUP BY (SUM, AVG, etc.) sans agréger l'ensemble de résultats (c'est-à-dire supprimer les enregistrements correspondants).

Cela est utile lorsque vous utilisez les fonctions LAST OVER ou MIN OVER pour obtenir, par exemple, le salaire le plus bas et le salaire le plus élevé dans le département, puis utilisez-le dans un calcul par rapport à celui-ci enregistre salaire sans une sous-sélection, ce qui est beaucoup plus rapide.

Lisez le lien article AskTom pour plus de détails.

243
Guy

Le concept est très bien expliqué par la réponse acceptée, mais je trouve que plus on voit d’exemples, mieux on les engloutit. Voici un exemple incrémental:

1) dit le patron "donnez-nous le nombre d'articles que nous avons en stock, groupé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, donnez-moi 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 ici que la OVER (PARTITION BY BRAND) entre:

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

Qui signifie:

  • COUNT(ITEM_ID) - récupère le nombre d'éléments
  • OVER - Sur l'ensemble des 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...

137
Andrejs

C'est l'extension SQL appelée analytics. Le "sur" dans l'instruction select indique à Oracle que la fonction est une fonction analytique, pas un groupe par fonction. L'avantage de l'utilisation des outils d'analyse est que vous pouvez collecter des sommes, des comptes et bien plus encore en un seul passage des données au lieu de les parcourir en boucle avec des sous-sélections ou pire, PL/SQL.

Cela semble déroutant au début, mais ce sera rapidement une seconde nature. Personne ne l'explique mieux que Tom Kyte. Donc, le lien ci-dessus est génial.

Bien sûr, la lecture de la documentation est un must.

26
user60890
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 compte pour deptno respectifs. Pour ce qui est de deptno 10, nous avons 4 enregistrements dans le tableau avec des résultats similaires pour deptno 20 et 30 également.

10
VISHAL PANDEY

le mot clé over partition est comme si nous partitionnions les données par client_id créant 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 retournera le nombre d'opérations effectuées par le client_id

2
issam