404 Not Found

404 Not Found


nginx

MySQLの集計関数とGROUP BYの詳細な解説

集計関数はデータ分析の中核をなすものであり、統計、グループ化、要約はすべてこれに基づいています。

このレッスンでは、集計関数とグループ化クエリについて詳しく解説します。

100%
graph TB
    A[Aggregate Query Process] --> B[FROM Data Sources]
    B --> C[WHERE Filter Rows]
    C --> D[GROUP BY Grouping]
    D --> E[Aggregate Functions<br/>COUNT/SUM/AVG/MAX/MIN]
    E --> F[HAVING Filter Group]
    F --> G[SELECT Output]
    G --> H[ORDER BY Sort]
    H --> I[WITH ROLLUP Summary]

1. 学習内容


2. 報告書の統計データに隠された実話

(1) 課題:Excelはデータ分析を行うには処理が遅すぎる

オペレーションマネージャーは、各部門の従業員数、平均給与、および最高給与に関する統計をまとめる必要があります。

Excelを使用するには、複数の数式を入力する必要があり、データが更新されるたびに計算をやり直さなければなりません。

(2) 集計関数の解法

SQL
SELECT 
    department,
    COUNT(*) AS emp_count,
    AVG(salary) AS avg_salary,
    MAX(salary) AS max_salary
FROM employees
GROUP BY department;

3. 集計関数

(1) COUNT

SQL
-- Count the total number of lines
SELECT COUNT(*) FROM employees;

-- Count non-NULL rows
SELECT COUNT(email) FROM employees;

-- Count the number of unique entries
SELECT COUNT(DISTINCT department) FROM employees;
⚠️ 注: COUNT(*) はすべての行をカウントしますが、COUNT(col) は col が NULL ではない行のみをカウントします。

(2) SUM/AVG:合計/平均

SQL
-- Total Wages
SELECT SUM(salary) FROM employees;

-- Average Wage
SELECT AVG(salary) FROM employees;

-- Conditional Summation
SELECT SUM(amount) FROM orders WHERE status = 'paid';

(3) MAX/MIN 最大値/最小値

SQL
-- Highest Salary
SELECT MAX(salary) FROM employees;

-- Minimum Wage
SELECT MIN(salary) FROM employees;

-- Earliest/Latest Date
SELECT MIN(hire_date) AS earliest, MAX(hire_date) AS latest FROM employees;

4. GROUP BY

▶ 例:単一フィールドによるグループ化

SQL
-- By Department
SELECT 
    department,
    COUNT(*) AS emp_count,
    AVG(salary) AS avg_salary
FROM employees
GROUP BY department;
▶ 試してみよう

出力:

TEXT
+-------------+-----------+-----------+
| department  | emp_count | avg_salary|
+-------------+-----------+-----------+
| Engineering |        15 |   8500.00 |
| Sales       |        10 |   6000.00 |
| Marketing   |         8 |   5500.00 |
| HR          |         5 |   5000.00 |
+-------------+-----------+-----------+

▶ 例:複数フィールドによるグループ化

SQL
-- By department and job title
SELECT 
    department,
    job_title,
    COUNT(*) AS count,
    AVG(salary) AS avg_salary
FROM employees
GROUP BY department, job_title
ORDER BY department, avg_salary DESC;
▶ 試してみよう

▶ 例:式によるグループ化

SQL
-- Orders by Year
SELECT 
    YEAR(order_date) AS year,
    COUNT(*) AS order_count,
    SUM(amount) AS total_amount
FROM orders
GROUP BY YEAR(order_date);

-- Statistics by Age Group
SELECT 
    CASE 
        WHEN age < 18 THEN 'Under 18'
        WHEN age BETWEEN 18 AND 30 THEN '18-30'
        WHEN age BETWEEN 31 AND 50 THEN '31-50'
        ELSE 'Over 50'
    END AS age_group,
    COUNT(*) AS count
FROM users
GROUP BY age_group;
▶ 試してみよう

5. HAVINGによるフィルタリングとグループ化

WHERE は行を絞り込み、HAVING はグループを絞り込みます。

▶ 例:HAVING の使用

SQL
-- Find the average wage > 6000 the department
SELECT 
    department,
    AVG(salary) AS avg_salary
FROM employees
GROUP BY department
HAVING avg_salary > 6000;

-- Find the number of orders > 10 's customers
SELECT 
    customer_id,
    COUNT(*) AS order_count,
    SUM(amount) AS total_amount
FROM orders
GROUP BY customer_id
HAVING order_count > 10;

-- WHERE + GROUP BY + HAVING Combination
SELECT 
    department,
    AVG(salary) AS avg_salary
FROM employees
WHERE hire_date >= '2024-01-01'  -- Filter the rows first
GROUP BY department               -- Regroup
HAVING avg_salary > 6000;        -- Final Filter Group
▶ 試してみよう

6. WITH ROLLUP の概要

▶ 例:ROLLUP 集計行

SQL
-- Automatically generate total rows
SELECT 
    department,
    COUNT(*) AS emp_count,
    SUM(salary) AS total_salary
FROM employees
GROUP BY department WITH ROLLUP;
▶ 試してみよう

出力:

TEXT
+-------------+-----------+--------------+
| department  | emp_count | total_salary |
+-------------+-----------+--------------+
| Engineering |        15 |    127500.00 |
| Sales       |        10 |     60000.00 |
| Marketing   |         8 |     44000.00 |
| HR          |         5 |     25000.00 |
| NULL        |        38 |    256500.00 |  -- Total
+-------------+-----------+--------------+

7. 集計関数とNULL

関数 NULL の扱い
COUNT(*) NULL行が含まれています
COUNT(col) NULLを除外
SUM(col) NULLを無視
AVG(col) NULLを無視(分母にNULLが含まれていない)
MAX(col) NULLを無視
MIN(col) NULLを無視

▶ 例:NULL値の扱い

SQL
-- COUNT(*) vs COUNT(email)
SELECT 
    COUNT(*) AS total_rows,
    COUNT(email) AS has_email,
    COUNT(*) - COUNT(email) AS no_email
FROM users;

-- AVG Ignore NULL
SELECT AVG(salary) FROM employees;  -- NULL Not included in the calculation
▶ 試してみよう

❓ よくある質問

Q WHERE と HAVING は併用できますか?
A はい。実行順序は、WHERE(行のフィルタリング)→ GROUP BY(グループ化)→ HAVING(グループのフィルタリング)→ SELECT → ORDER BY です。
Q GROUP BY 句のフィールドは、SELECT 句にも含める必要がありますか?
A MySQL の厳格モードでは、SELECT 句に含まれる集計対象外のフィールドは、GROUP BY 句にも含める必要があります。
Q COUNT(*) と COUNT(1) のどちらが速いですか?
A どちらも同じくらい速いです。MySQL のオプティマイザが自動的に最適な方法を選択します。
Q 集計関数はネストできますか?
A 直接ネストすることはできません AVG(SUM(...))。サブクエリを使用してください:SELECT AVG(total) FROM (SELECT SUM(amount) AS total FROM orders GROUP BY customer_id) t

📖 まとめ


📝 練習問題

  1. 基本問題(難易度:⭐):各部署の従業員数と平均給与を算出してください。

  2. 応用問題(難易度 ⭐⭐):注文総額が 10,000 を超える顧客を特定し、総額の多い順に並べ替えてください。

  3. 課題(難易度:⭐⭐⭐):各月の注文数、合計金額、平均金額を算出し、WITH ROLLUP を使用して年間の集計行を追加してください。

Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%