MySQL - GROUP BY 子句



MySQL GROUP BY 子句

MySQL 中的GROUP BY 子句用於將表中相同的資料整理成組。

例如,假設您有一個組織的銷售資料表,其中包含日期、產品和銷售額。要計算特定年份的總銷售額,可以使用 GROUP BY 子句對該年份的產品銷售額進行分組。類似地,您可以按日期對資料進行分組以計算每天的總銷售額,或者按產品和日期的組合對資料進行分組以計算每天每種產品的總銷售額。

此 GROUP BY 子句位於 SQL 語句中的 WHERE 子句之後,並且位於 ORDER BY 或 HAVING 子句(如果存在)之前。您可以使用GROUP BY 對來自某列的值進行分組,並且如果需要,可以對該列執行計算。您可以在分組列上使用 COUNT、SUM、AVG 等函式。

語法

以下是使用 GROUP BY 與 SELECT 語句的基本語法:

SELECT column_name(s) FROM table_name
GROUP BY [condition | column_name(s)];

示例

此示例演示如何將聚合函式與 GROUP BY 子句一起使用。

首先,使用以下 CREATE TABLE 查詢建立一個名為CUSTOMERS的表:

CREATE TABLE CUSTOMERS (
   ID INT NOT NULL,
   NAME VARCHAR (20) NOT NULL,
   AGE INT NOT NULL,
   ADDRESS CHAR (25),
   SALARY DECIMAL (18, 2),       
   PRIMARY KEY (ID)
);

現在,使用以下 INSERT 語句將以下記錄插入 CUSTOMERS 表中:

INSERT INTO CUSTOMERS VALUES
(1, 'Ramesh', 32, 'Ahmedabad', 2000.00),
(2, 'Khilan', 25, 'Delhi', 1500.00),
(3, 'Kaushik', 23, 'Kota', 2000.00),
(4, 'Chaitali', 25, 'Mumbai', 6500.00),
(5, 'Hardik', 27, 'Bhopal', 8500.00),
(6, 'Komal', 22, 'Hyderabad', 4500.00),
(7, 'Muffy', 24, 'Indore', 10000.00);

表建立如下:

ID NAME AGE ADDRESS SALARY
1 Ramesh 32 Ahmedabad 2000.00
2 Khilan 25 Delhi 1500.00
3 Kaushik 23 Kota 2000.00
4 Chaitali 25 Mumbai 6500.00
5 Hardik 27 Bhopal 8500.00
6 Komal 22 Hyderabad 4500.00
7 Muffy 24 Indore 10000.00

現在,使用以下 GROUP BY 查詢根據客戶的年齡對客戶進行分組:

SELECT AGE, COUNT(Name) FROM CUSTOMERS GROUP BY AGE;

輸出

以下是生成的輸出結果:

AGE COUNT(Name)
32 1
25 2
23 1
27 1
22 1
24 1

MySQL 單列 GROUP BY

當我們在單個列上使用 GROUP BY 子句時,該列中的所有公共值將加在一起,使其成為一條記錄。

示例

在此示例中,讓我們按年齡對客戶進行分組,並使用以下查詢計算每個年齡的平均工資:

SELECT AGE, AVG(SALARY) AS AVG_SALARY 
FROM CUSTOMERS 
GROUP BY AGE;

輸出

這將產生以下結果:

AGE AVG_SALARY
32 2000.000000
25 4000.000000
23 2000.000000
27 8500.000000
22 4500.000000
24 10000.000000

MySQL 多列 GROUP BY

當我們將 GROUP BY 子句與多個列一起使用時,透過組合這些列中的值獲得的公共記錄將分組到單個記錄中。

示例

在此示例中,如果您想知道每個客戶的年齡對應的工資總額,則 GROUP BY 查詢如下所示:

SELECT CONCAT(AGE, ' - ', SALARY) AS SALARY_AGEWISE 
FROM CUSTOMERS 
GROUP BY AGE, SALARY;

輸出

這將產生以下結果:

SALARY_AGEWISE
32 - 2000.00
25 - 1500.00
23 - 2000.00
25 - 6500.00
27 - 8500.00
22 - 4500.00
24 - 10000.00

MySQL GROUP BY 與 ORDER BY 子句

我們可以在 MySQL 中將 ORDER BY 子句與 GROUP BY 一起使用,以根據一個或多個列對結果集進行排序。

語法

以下是 SQL 中使用 ORDER BY 子句與 GROUP BY 子句的語法:

SELECT column1, column2, ..., aggregate_function(columnX) AS alias
FROM table
GROUP BY column1, column2, ...
ORDER BY column1 [ASC | DESC], column2 [ASC | DESC], ...;

示例

在這裡,我們試圖找到每個年齡的最高工資,並按從高到低的順序排序:

SELECT AGE, MAX(salary) AS MAX_SALARY 
FROM CUSTOMERS 
GROUP BY AGE 
ORDER BY MAX(salary) DESC;

輸出

這將產生以下結果:

AGE AVG_SALARY
24 10000.00
27 8500.00
25 6500.00
22 4500.00
32 2000.00
23 2000.00

MySQL GROUP BY 與 HAVING 子句

我們還可以將 GROUP BY 子句與 HAVING 子句一起使用,以根據應用於資料組的條件過濾查詢的結果。該條件可以應用於 SELECT 語句中使用的聚合函式或 GROUP BY 子句中的列。

語法

以下是 SQL 中使用 ORDER BY 子句與 HAVING 子句的語法:

SELECT column1, column2, aggregate_function(column)
FROM table_name
GROUP BY column1, column2
HAVING condition;

示例

在下面的查詢中,我們根據客戶的年齡對他們進行分組,並計算每個組的平均工資。HAVING 子句用於過濾結果,只顯示平均工資大於 8000 的組。

SELECT AGE, AVG(SALARY) AS AVG_SALARY 
FROM CUSTOMERS 
GROUP BY AGE HAVING AVG(salary) > 8000;

輸出

這將產生以下結果:

AGE AVG_SALARY
27 8500.000000
24 10000.000000

使用客戶端程式的 GROUP BY 子句

除了在 MySQL 伺服器中使用 SQL 查詢與 GROUP BY 子句一起使用之外,我們還可以使用客戶端程式執行 GROUP BY 子句。

語法

以下是各種程式語言中 select 語句中 Group by 子句的語法:

要在 PHP 程式中透過 MySQL 表使用 GROUP BY 子句,我們需要使用 mysqli 聯結器提供的名為 query() 的函式執行 SQL 語句。

$sql = "SELECT EXPRESSION1, EXPRESSION2, ... EXPRESSION_N,
   AGGREGATE_FUNCTION(EXPRESSION) FROM TABLE_NAME
   [WHERE CONDITION] GROUP BY EXPRESSION1, EXPRESSION2..";
$mysqli->query($sql,$resultmode)

要在 JavaScript 程式中透過 MySQL 表使用 GROUP BY 子句,我們需要使用 mysql2 聯結器提供的名為 query() 的函式執行 SQL 語句。

sql= " SELECT column_name(s) FROM table_name
   GROUP BY [condition | column_name(s)];"
Con.query(sql);

要在 Java 程式中透過 MySQL 表使用 GROUP BY 子句,我們需要使用 JDBC type 4 驅動程式提供的名為 executeQuery() 的函式執行 SQL 語句。

String sql = "SELECT column_name(s) FROM table_name
   GROUP BY [condition | column_name(s)]";
statement.executeQuery(sql);

要在 Java 程式中透過 MySQL 表使用 GROUP BY 子句,我們需要使用 MySQL Connector/Python 提供的名為 execute() 的函式執行 SQL 語句。

group_by_clause_query = "SELECT column_name(s) aggregate_function(column)
   FROM table_name GROUP BY column_name(s)"
cursorObj.execute(group_by_clause_query)

示例

以下是使用各種程式語言實現 GROUP BY 的示例:

$dbhost = 'localhost';
$dbuser = 'root';
$dbpass = 'password';
$dbname = 'TUTORIALS';
$mysqli = new mysqli($dbhost, $dbuser, $dbpass, $dbname);
if($mysqli->connect_errno ) {
   printf("Connect failed: %s
", $mysqli->connect_error); exit(); } //printf('Connected successfully.
'); $sql = 'SELECT tutorial_title, count(tutorial_id) AS tot_count FROM tutorials_tbl WHERE tutorial_id > 2 GROUP BY tutorial_title'; $result = $mysqli->query($sql); if ($result->num_rows > 0) { printf("Table records: \n"); while($row = $result->fetch_assoc()) { printf("Title: %s, Count: %d", $row["tutorial_title"], $row["tot_count"]); printf("\n"); } } else { printf('No record found.
'); } mysqli_free_result($result); $mysqli->close();

輸出

獲得的輸出如下所示:

Table records:
Title: JAVA Tutorial, Count: 1
Title: Learn PHP, Count: 1
Title: Learn MySQL, Count: 2
var mysql = require('mysql2');
var con = mysql.createConnection({
    host: "localhost",
    user: "root",
    password: "Nr5a0204@123"
});

  //Connecting to MySQL
  con.connect(function (err) {
  if (err) throw err;
  console.log("Connected!");
  console.log("--------------------------");

  //Creating a Database
  sql = "create database TUTORIALS"
  con.query(sql);

  //Select database
  sql = "USE TUTORIALS"
  con.query(sql);

  //Creating table
  sql = "CREATE TABLE IF NOT EXISTS employee_tbl(id INT NOT NULL, name VARCHAR(100) NOT NULL, work_date DATE, daily_typing_pages INT);"
  con.query(sql);

  //Inserting Records
  sql = "INSERT INTO employee_tbl(id, name, work_date, daily_typing_pages) VALUES(1, 'John', '2007-01-24', 250), (2, 'Ram', '2007-05-27', 220), (3, 'Jack', '2007-05-06', 170), (3, 'Jack', '2007-04-06', 100), (4, 'Jill', '2007-04-06', 220),(5, 'Zara', '2007-06-06', 300),(5, 'Zara', '2007-02-06', 350);"
  con.query(sql);

  //Using GROUP BY Clause
  sql = "SELECT name, COUNT(*) FROM employee_tbl GROUP BY name;"
  con.query(sql, function(err, result){
    if (err) throw err
    console.log(result)
  });
});

輸出

產生的輸出如下所示:

Connected!
--------------------------
[
  { name: 'John', 'COUNT(*)': 1 },
  { name: 'Ram', 'COUNT(*)': 1 },
  { name: 'Jack', 'COUNT(*)': 2 },
  { name: 'Jill', 'COUNT(*)': 1 },
  { name: 'Zara', 'COUNT(*)': 2 }
]
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class GroupByClause {
	public static void main(String[] args) {
		String url = "jdbc:mysql://:3306/TUTORIALS";
		String user = "root";
		String password = "password";
		ResultSet rs;
		try {
			Class.forName("com.mysql.cj.jdbc.Driver");
            Connection con = DriverManager.getConnection(url, user, password);
            Statement st = con.createStatement();
            //System.out.println("Database connected successfully...!");
            String sql = "SELECT AGE, AVG(SALARY) as avg_salary FROM CUSTOMERS GROUP BY age";
            rs = st.executeQuery(sql);
            System.out.println("Table records(gruop by age): ");
            while(rs.next()){
            	String age = rs.getString("Age");
            	String avg_salary = rs.getString("avg_salary");
            	System.out.println("Age: " + age + ", Salary: " + avg_salary);
            }
		}catch(Exception e) {
			e.printStackTrace();
		}
	}
}

輸出

獲得的輸出如下所示:

Table records(gruop by age): 
Age: 32, Salary: 2000.000000
Age: 25, Salary: 4000.000000
Age: 23, Salary: 2000.000000
Age: 27, Salary: 8500.000000
Age: 22, Salary: 4500.000000
Age: 24, Salary: 10000.000000
import mysql.connector
#establishing the connection
connection = mysql.connector.connect(
    host='localhost',
    user='root',
    password='password',
    database='tut'
)
# Creating a cursor object 
cursorObj = connection.cursor()
group_by_clause_query = """
SELECT ADDRESS, AVG(SALARY) AS average_salary
FROM customers
GROUP BY ADDRESS
"""
cursorObj.execute(group_by_clause_query)
# Fetching all the grouped rows
grouped_rows = cursorObj.fetchall()
for row in grouped_rows:
    address, average_salary = row
    print(f"Address: {address}, Average Salary: {average_salary}")
cursorObj.close()
connection.close()

輸出

以下是上述程式碼的輸出:

Address: Hyderabad, Average Salary: 7500.000000
Address: Kerala, Average Salary: 8000.000000
Address: Mumbai, Average Salary: 1200.000000
Address: Vishakapatnam, Average Salary: 8500.000000
Address: Delhi, Average Salary: 10000.000000
廣告