How a SQL SELECT statement works

In this topic, I'll talk about the procedure of execution for a SQL SELECT statement.

Basically there're 6 steps for a query:

1. Get Data                                 - FROM, JOIN
2. Filter Row                               - WHERE
3. Group                                     - GROUP BY
4. Group Filter                            - HAVING
5. Return Selected Result         - SELECT
6. Order or Page                        - ORDER BY/LIMIT/OFFSET

0. Prepare the data.

Here I will use two tables to demonstrate the process.

CREATE DATABASE dbtest;
USE dbtest;
CREATE TABLE employees(employee_name VARCHAR(30) NOT NULL, department_id INT);
CREATE TABLE departments(department_id INT NOT NULL, department_name VARCHAR(30));
INSERT INTO departments VALUES(1, 'HR');
INSERT INTO departments VALUES(2, 'R&D');
INSERT INTO departments VALUES(3, 'Marketing');
INSERT INTO departments VALUES(4, 'Sales');
INSERT INTO employees VALUES('Andy', 1);
INSERT INTO employees VALUES('Bob', 2);
INSERT INTO employees VALUES('Candy',3);
INSERT INTO employees VALUES('David',1);
INSERT INTO employees VALUES('Ella',2);
INSERT INTO employees VALUES('Fann',1);
INSERT INTO employees VALUES('Gary',4);
INSERT INTO employees VALUES('Henry',4);
INSERT INTO employees VALUES('Ivy',4);
INSERT INTO employees VALUES('Jack',4);

We use the below statement to explain the process.

SELECT d.department_name AS "Department Name"
FROM employees e
JOIN departments d
ON e.department_id = d.department_id 
WHERE d.department_name != 'Marketing'
GROUP BY d.department_name
HAVING COUNT(*) >= 3
ORDER BY d.department_name DESC
LIMIT 1;

1. Get data

The first step is to get the data by FROM and JOIN. It will return the cardisian product. We have 10 * 4 = 40 rows in this result. It's equal to:

SELECT *
FROM employees e
JOIN departments d;
employee_namedepartment_iddepartment_iddepartment_name
Andy14Sales
Andy13Marketing
Andy12R&D
Andy11HR
Bob24Sales
Bob23Marketing
Bob22R&D
Bob21HR
Candy34Sales
Candy33Marketing
Candy32R&D
Candy31HR
David14Sales
David13Marketing
David12R&D
David11HR
Ella24Sales
Ella23Marketing
Ella22R&D
Ella21HR
Fann14Sales
Fann13Marketing
Fann12R&D
Fann11HR
Gary44Sales
Gary43Marketing
Gary42R&D
Gary41HR
Henry44Sales
Henry43Marketing
Henry42R&D
Henry41HR
Ivy44Sales
Ivy43Marketing
Ivy42R&D
Ivy41HR
Jack44Sales
Jack43Marketing
Jack42R&D
Jack41HR

Based on above cardisian product, the ON condition will be applied to it. It will return 10 rows.

It's like the statement.

SELECT *
FROM employees e
JOIN departments d
ON e.department_id = d.department_id;
employee_namedepartment_iddepartment_iddepartment_name
Andy11HR
Bob22R&D
Candy33Marketing
David11HR
Ella22R&D
Fann11HR
Gary44Sales
Henry44Sales
Ivy44Sales
Jack44Sales

2. Filter Rows by WHERE

Then WHERE clause is applied to get the qualified rows. It will return 9 rows.

SELECT *
FROM employees e
JOIN departments d
ON e.department_id = d.department_id
WHERE d.department_name != 'Marketing';
employee_namedepartment_iddepartment_iddepartment_name
Andy11HR
Bob22R&D
David11HR
Ella22R&D
Fann11HR
Gary44Sales
Henry44Sales
Ivy44Sales
Jack44Sales

3. Group the data with GROUP BY

GROUP BY d.department_name;

Based on the department name, it will group the data. It also has 3 rows like the way:

employee_namedepartment_iddepartment_iddepartment_name
Andy11HR
Fann11
David11
Bob22R&D
Ella22
Gary44Sales
Henry44
Ivy44
Jack44

4. Group filter by HAVING

HAVING COUNT(*) >= 3

Only HR and Sales which has at least 3 employees are left.

employee_namedepartment_iddepartment_iddepartment_name
Andy11HR
Fann11
David11
Gary44Sales
Henry44
Ivy44
Jack44

5. Return selected result 

Then execute SELECT clause:

SELECT d.department_name AS "Department Name"
FROM employees e
JOIN departments d
ON e.department_id = d.department_id 
WHERE d.department_name != 'Marketing'
GROUP BY d.department_name
HAVING COUNT(*) >= 3;
Department Name
HR
Sales

6. Order or Page

ORDER BY is applied to the result in Step 5:

SELECT d.department_name AS "Department Name"
FROM employees e
JOIN departments d
ON e.department_id = d.department_id 
WHERE d.department_name != 'Marketing'
GROUP BY d.department_name
HAVING COUNT(*) >= 3
ORDER BY d.department_name DESC;
Department Name
Sales
HR

Finally LIMIT is applied. Only the first record is returned after LIMIT 1:

SELECT d.department_name AS "Department Name"
FROM employees e
JOIN departments d
ON e.department_id = d.department_id 
WHERE d.department_name != 'Marketing'
GROUP BY d.department_name
HAVING COUNT(*) >= 3
ORDER BY d.department_name DESC
LIMIT 1;
Department Name
Sales

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值