PARTITION BYとGROUP BYの違いについて

## **概要**
本記事では、BigQueryでの「パーティション（`PARTITION BY`）」と「グループ（`GROUP BY`）」の違いについて、サンプルデータを基に実例を示します。それぞれの結果がどのように異なるのかを明確に理解するため、SQLクエリの出力も説明します。


## **ステップ 1: サンプルテーブルの作成**

以下のSQLを実行して、サンプルテーブル `data-sandbox.test.employees` を作成します。

### **サンプルデータ**
社員の部門（`department`）、名前（`employee`）、給与（`salary`）が含まれています。

```sql
CREATE OR REPLACE TABLE `data-sandbox.test.employees` AS
SELECT 'HR' AS department, 'Alice' AS employee, 5000 AS salary UNION ALL
SELECT 'HR', 'Bob', 4500 UNION ALL
SELECT 'HR', 'Charlie', 5500 UNION ALL
SELECT 'IT', 'Dave', 7000 UNION ALL
SELECT 'IT', 'Eve', 8000 UNION ALL
SELECT 'IT', 'Frank', 7500 UNION ALL
SELECT 'Finance', 'Grace', 6000 UNION ALL
SELECT 'Finance', 'Hank', 6500 UNION ALL
SELECT 'Finance', 'Ivy', 6200;
```

**テーブルの内容:**

| department | employee | salary |
|------------|----------|--------|
| HR         | Alice    | 5000   |
| HR         | Bob      | 4500   |
| HR         | Charlie  | 5500   |
| IT         | Dave     | 7000   |
| IT         | Eve      | 8000   |
| IT         | Frank    | 7500   |
| Finance    | Grace    | 6000   |
| Finance    | Hank     | 6500   |
| Finance    | Ivy      | 6200   |


## **ステップ 2: GROUP BYを使用した集計**

部門ごとの合計給与（`department_total_salary`）を計算するクエリです。

```sql
SELECT
  department,
  SUM(salary) AS department_total_salary
FROM `data-sandbox.test.employees`
GROUP BY department;
```

**結果:**
![スクリーンショット 2024-11-24 23.08.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3364428/00afe21f-befb-094e-5772-6ceb878d6924.png)


**解説:**
- `GROUP BY` で部門ごとに行をまとめ、給与を合計しました。
- 各部門に対して1行だけが結果として出力されます。

## **ステップ 3: PARTITION BYを使用したウィンドウ関数**

部門ごとに各社員の給与と部門の合計給与を併せて表示します。

```sql
SELECT
  department,
  employee,
  salary,
  SUM(salary) OVER (PARTITION BY department) AS department_total_salary
FROM `data-sandbox.test.employees`;
```

**結果:**
![スクリーンショット 2024-11-24 22.45.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3364428/751db928-118a-a4f5-1ae1-c096162e9813.png)

**解説:**
- `PARTITION BY department` で部門ごとにデータを分けて、それぞれの合計給与を計算しています。
- 元の行数を保ちながら、部門ごとの合計値が繰り返し表示されます。


## **ステップ 4: パーティションとグループの違いのまとめ**

| 特徴            | GROUP BY                              | PARTITION BY                          |
|-----------------|--------------------------------------|--------------------------------------|
| **目的**         | データを集約して1行にまとめる         | データを分割しつつ行ごとに計算を適用 |
| **結果の行数**   | グループ単位で1行                   | 元の行数を保持                       |
| **使用例**       | 部門ごとの売上合計を計算             | 部門ごとの売上合計を元の行に表示     |
| **適用箇所**     | 集約クエリ                          | ウィンドウ関数                       |


## **ステップ 5: 応用クエリ**

**部門ごとの給与ランキングを計算する例（PARTITION BYを応用）:**

```sql
SELECT
  department,
  employee,
  salary,
  RANK() OVER (PARTITION BY department ORDER BY salary DESC) AS salary_rank
FROM `data-sandbox.test.employees`;
```

**結果:**
![スクリーンショット 2024-11-24 23.07.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3364428/cd32b180-9f94-454c-35f5-7f7dab60e260.png)



## **結論**

- **GROUP BY** はデータをまとめて集計するのに最適で、グループごとに1行の結果が必要な場合に使用します。
- **PARTITION BY** はデータを分割してウィンドウ関数を適用する際に使い、行ごとの計算や分析に便利です。

BigQueryでの集計や分析の際、用途に応じて適切な手法を選択してください！