1. 基本查询
查询所有列
select * from employees;
SELECT:这是 SQL 中用于从数据库表中选取数据的关键字。
*:是一个通配符,表示选取表中的所有列。
FROM employees:指定数据来源表为 employees,即从 employees 表中选取所有列的数据。
查询特定列
select name, age from employees;
SELECT name, age:明确指定要从表中选取的列是 name 和 age。
FROM employees:同样指定数据来源于 employees 表。
2. 带条件查询
使用 where 子句
select * from employees where age > 30;
SELECT *:选取 employees 表中的所有列。
FROM employees:指定数据来源表。
WHERE age > 30:WHERE 子句用于筛选数据,这里表示只选取 age 列的值大于 30 的记录。
使用 and 和 or
select * from employees where age > 30 and department = 'hr';
SELECT *:选取所有列。
FROM employees:指定数据来源。
WHERE age > 30 AND department = 'hr':AND 是逻辑运算符,要求 age 列的值大于 30 并且 department 列的值为 'hr' 的记录才会被选取。
select * from employees where age > 30 or department = 'hr';
SELECT *:选取所有列。
FROM employees:指定数据来源。
WHERE age > 30 OR department = 'hr':OR 是逻辑运算符,只要 age 列的值大于 30 或者 department 列的值为 'hr' 的记录就会被选取。
3. 排序查询
使用 order by
select * from employees order by age desc;
SELECT *:选取所有列。
FROM employees:指定数据来源。
ORDER BY age DESC:ORDER BY 用于对查询结果进行排序,age 是排序的列,DESC 表示降序排列,即按照 age 列的值从大到小排序。
select * from employees order by department, age;
SELECT *:选取所有列。
FROM employees:指定数据来源。
ORDER BY department, age:先按照 department 列的值进行升序排序,对于 department 列值相同的记录,再按照 age 列的值进行升序排序。
4. 分组查询
使用 group by
select department, count(*) from employees group by department;
SELECT department, count(*):选取 department 列,同时使用 COUNT(*) 聚合函数统计每个分组中的记录数量。
FROM employees:指定数据来源。
GROUP BY department:GROUP BY 用于将数据按照 department 列的值进行分组,然后对每个分组应用聚合函数。
带条件的分组查询
select department, count(*) from employees group by department having count(*) > 2;
SELECT department, count(*):选取 department 列和每个分组的记录数量。
FROM employees:指定数据来源。
GROUP BY department:按 department 列分组。
HAVING count(*) > 2:HAVING 子句用于筛选分组后的结果,只保留记录数量大于 2 的分组。
5. 子查询
简单子查询
select name from employees where department = (select department from employees where name = 'alice');
SELECT name:选取 name 列。
FROM employees:指定数据来源。
WHERE department = (select department from employees where name = 'alice'):子查询 (select department from employees where name = 'alice') 会返回姓名为 'alice' 的员工所在的部门,外部查询则选取 department 列的值等于该子查询结果的员工姓名。
多行子查询
select name from employees where department in (select department from employees where age > 30);
SELECT name:选取 name 列。
FROM employees:指定数据来源。
WHERE department IN (select department from employees where age > 30):子查询 (select department from employees where age > 30) 会返回年龄大于 30 的员工所在的所有部门,外部查询则选取 department 列的值在这些部门中的员工姓名。
6. 连接查询
内连接
select e.name, d.department_name
from employees e
inner join departments d on e.department_id = d.id;
SELECT e.name, d.department_name:选取 employees 表中的 name 列和 departments 表中的 department_name 列。
FROM employees e:指定 employees 表,并为其取别名 e。
INNER JOIN departments d:使用 INNER JOIN 进行内连接操作,将 employees 表和 departments 表连接起来,为 departments 表取别名 d。
ON e.department_id = d.id:ON 子句指定连接条件,即 employees 表中的 department_id 列的值等于 departments 表中的 id 列的值,只有满足该条件的记录才会出现在结果中。
左连接
select e.name, d.department_name
from employees e
left join departments d on e.department_id = d.id;
SELECT e.name, d.department_name:选取相应列。
FROM employees e:指定 employees 表并取别名。
LEFT JOIN departments d:使用 LEFT JOIN 进行左连接操作,以 employees 表为主表,即使 departments 表中没有匹配的记录,employees 表中的记录也会出现在结果中。
ON e.department_id = d.id:指定连接条件。
右连接
select e.name, d.department_name
from employees e
right join departments d on e.department_id = d.id;
SELECT e.name, d.department_name:选取相应列。
FROM employees e:指定 employees 表并取别名。
RIGHT JOIN departments d:使用 RIGHT JOIN 进行右连接操作,以 departments 表为主表,即使 employees 表中没有匹配的记录,departments 表中的记录也会出现在结果中。
ON e.department_id = d.id:指定连接条件。
7. 限制结果
使用 limit
select * from employees limit 5;
SELECT *:选取所有列。
FROM employees:指定数据来源。
LIMIT 5:LIMIT 用于限制查询结果的行数,这里表示只返回前 5 条记录。
select * from employees limit 5 offset 5;
SELECT *:选取所有列。
FROM employees:指定数据来源。
LIMIT 5 OFFSET 5:OFFSET 表示偏移量,这里表示跳过前 5 条记录,然后返回接下来的 5 条记录。
8. 去重
使用 distinct
select distinct department from employees;
SELECT DISTINCT department:DISTINCT 关键字用于去除查询结果中的重复记录,这里表示选取 employees 表中 department 列的所有不同值。
9. 重命名列
使用 as
select name as employee_name, age as employee_age from employees;
SELECT name AS employee_name, age AS employee_age:AS 关键字用于为列取别名,这里将 name 列重命名为 employee_name,将 age 列重命名为 employee_age,方便在结果中引用。
10. 条件判断
使用 case
select name,
case
when age < 30 then 'young'
when age >= 30 and age < 40 then 'middle-aged'
else 'senior'
end as age_group
from employees;
SELECT name:选取 name 列。
CASE:CASE 语句用于进行条件判断。
WHEN age < 30 THEN 'young':如果 age 列的值小于 30,则返回 'young'。
WHEN age >= 30 AND age < 40 THEN 'middle-aged':如果 age 列的值大于等于 30 且小于 40,则返回 'middle-aged'。
ELSE 'senior':如果以上条件都不满足,则返回 'senior'。
END AS age_group:END 表示 CASE 语句结束,AS age_group 为该计算结果取别名 age_group。
FROM employees:指定数据来源。
11. 模糊查询
使用 like
select * from employees where name like 'a%'; -- 以a开头
SELECT *:选取所有列。
FROM employees:指定数据来源。
WHERE name LIKE 'a%':LIKE 用于进行模糊匹配,'a%' 表示以 a 开头的任意字符串,这里表示只选取 name 列的值以 a 开头的记录。
select * from employees where name like '%a%'; -- 包含a
SELECT *:选取所有列。
FROM employees:指定数据来源。
WHERE name LIKE '%a%':'%a%' 表示包含 a 的任意字符串,这里表示只选取 name 列的值包含 a 的记录。
12. 范围查询
使用 between
select * from employees where age between 25 and 35;
SELECT *:选取所有列。
FROM employees:指定数据来源。
WHERE age BETWEEN 25 AND 35:BETWEEN 用于筛选某个范围内的值,这里表示只选取 age 列的值在 25 到 35 之间(包括 25 和 35)的记录。
13. 多值查询
使用 in
select * from employees where department in ('hr', 'it');
SELECT *:选取所有列。
FROM employees:指定数据来源。
WHERE department IN ('hr', 'it'):IN 用于判断某个值是否在指定的集合中,这里表示只选取 department 列的值为 'hr' 或 'it' 的记录。
14. 空值查询
使用 is null
select * from employees where department is null;
SELECT *:选取所有列。
FROM employees:指定数据来源。
WHERE department IS NULL:IS NULL 用于判断某个列的值是否为空,这里表示只选取 department 列的值为空的记录。
15. 表连接(与前面的连接查询重复,原理相同)
16. 子查询(与前面的子查询重复,原理相同)
17. 表别名
使用 as
select e.name, d.department_name
from employees as e
inner join departments as d on e.department_id = d.id;
SELECT e.name, d.department_name:选取相应列,使用别名引用。
FROM employees AS e:为 employees 表取别名 e。
INNER JOIN departments AS d:为 departments 表取别名 d,并进行内连接操作。
ON e.department_id = d.id:指定连接条件。
18. 排序(与前面的排序查询重复,原理相同)
19. 分组(与前面的分组查询重复,原理相同)
20. 过滤分组(与前面的带条件的分组查询重复,原理相同)
21. 连接多个表
多表连接
select e.name, d.department_name, s.salary
from employees e
inner join departments d on e.department_id = d.id
inner join salaries s on e.id = s.employee_id;
SELECT e.name, d.department_name, s.salary:选取 employees 表中的 name 列、departments 表中的 department_name 列和 salaries 表中的 salary 列。
FROM employees e:指定 employees 表并取别名。
INNER JOIN departments d ON e.department_id = d.id:将 employees 表和 departments 表进行内连接。
INNER JOIN salaries s ON e.id = s.employee_id:再将连接结果与 salaries 表进行内连接,连接条件是 employees 表中的 id 列的值等于 salaries 表中的 employee_id 列的值。
22. 合并查询结果
使用 union
select name from employees where department = 'hr'
union
select name from employees where department = 'it';
SELECT name FROM employees WHERE department = 'hr':选取 department 列的值为 'hr' 的员工姓名。
UNION:UNION 用于合并两个或多个 SELECT 语句的结果集,自动去除重复记录。
SELECT name FROM employees WHERE department = 'it':选取 department 列的值为 'it' 的员工姓名。
23. 复杂条件判断(与前面的条件判断重复,原理相同)
24. 分页查询(与前面的限制结果重复,原理相同)
25. 去重(与前面的去重重复,原理相同)
26. 重命名列(与前面的重命名列重复,原理相同)
27. 使用函数
字符串函数
select concat(name, ' is ', age, ' years old') as info from employees;
SELECT CONCAT(name, ' is ', age, ' years old') AS info:CONCAT 是字符串连接函数,将 name 列的值、字符串 ' is '、age 列的值和字符串 ' years old' 连接成一个新的字符串,AS info 为该结果取别名 info。
FROM employees:指定数据来源。
日期函数
select name, date_format(created_at, '%Y-%m-%d') as created_date from employees;
SELECT name:选取 name 列。
DATE_FORMAT(created_at, '%Y-%m-%d') AS created_date:DATE_FORMAT 是日期格式化函数,将 created_at 列的日期值按照 '%Y-%m-%d' 的格式进行格式化,AS created_date 为该结果取别名 created_date。
FROM employees:指定数据来源。
数学函数
select name, round(salary / 12, 2) as monthly_salary from salaries;
SELECT name:选取 name 列。
ROUND(salary / 12, 2) AS monthly_salary:ROUND 是四舍五入函数,将 salary 列的值除以 12 后保留 2 位小数,AS monthly_salary 为该结果取别名 monthly_salary。
FROM salaries:指定数据来源。