web-dev-qa-db-ja.com

Oracleの「Partition By」キーワード

誰かがpartition byキーワードが何をするのかを説明して、そして実際にそれの簡単な例を与えることができます、そして、なぜそれがそれを使いたいと思うでしょうか?私は誰か他の人によって書かれたSQLクエリを持っていて、それが何をするのか理解しようとしています。

以下によるパーティション分割の例

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

私がオンラインで見た例は少し深すぎるようです。

229
Alex Beardsley

PARTITION BY句は、OVER句内の各 "GROUP"に使用されるレコードの範囲を設定します。

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 BYSUMAVGなど)の結果を取得するのと同じです。

LAST OVERまたはMIN OVER関数を使用して、たとえば部門内の最低および最高の給与を取得してから、このレコードに対する計算でそれを使用すると便利です。給与withoutサブ選択、これははるかに高速です。

詳しくはリンクされた AskTomの記事 を読んでください。

238
Guy

その概念は、受け入れられた答えによって非常によく説明されています、しかし、私はより多くの例が見れば、それがより良く沈み込むことを見つける。

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

等...

127
Andrejs

それはanalyticsと呼ばれるSQLの拡張です。 select文の "over"は、関数が分析関数であり、関数によるグループではないことをOracleに伝えます。アナリティクスを使用する利点は、サブセレクトやさらに悪いことにPL/SQLを使用してデータをループするのではなく、データを1回パススルーするだけで合計、件数などを収集できることです。

最初は紛らわしいように見えますが、これはすぐに2番目の性質になります。誰もそれをトムKyteよりよく説明しません。だから上記のリンクは素晴らしいです。

もちろん、 ドキュメント を読むことは必須です。

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

ここでは、それぞれのdeptnoの数を数えています。 deptno 10については、テーブルempに4つのレコードがあり、deptno 20と30についても同様の結果が得られます。

10
VISHAL PANDEY

over partitionキーワードは、client_idを作成して各クライアント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によって実行された操作の数を返します。

2
issam