Mysql单表查询
Mysql单表查询
基本语法
SELECT column1, column2, aggregate_function(column3)
FROM table_name
[WHERE condition]
[GROUP BY column1, column2]
[HAVING condition]
[ORDER BY column_name [ASC|DESC]]
[LIMIT number];
-
DISTINCT:可选关键字,用于去除查询结果中的重复行
- DISTINCT 作用于所有选择的列:如果选择了多列,DISTINCT 会基于这些列的组合值去重
- DISTINCT 的性能:去重操作需要对结果集进行排序和比较,可能会影响查询性能,尤其是在大数据集上
- DISTINCT 与 NULL:如果列中包含 NULL 值,DISTINCT 会将所有 NULL 视为相同的值,只保留一个 NULL
- DISTINCT 可以与聚合函数一起使用,例如
COUNT(DISTINCT column_name),用于统计某列的唯一值数量
-
SELECT:指定要查询的列 -
FROM:指定要查询的表基础语法:
SELECT column1, column2, ... FROM table_name;-
使用 * 可以查询表中的所有列
SELECT * FROM employees; -
指定列名可以查询特定的列
SELECT first_name, last_name FROM employees; --只返回 first_name 和 last_name 列的数据- 列名的顺序决定了结果集中列的顺序
- 如果列名不存在,会报错
-
使用别名(AS),可以为列或表指定别名,使查询结果更易读
- 别名通常用于 SELECT 语句中,为表或列指定一个临时名称
- 别名可以使用 AS 关键字定义,也可以直接写在表名或列名后面
- 定义别名时,可以直接在列名或表名后面写上别名,而不需要使用 AS
- 如果省略 AS,别名必须紧跟在列名后面,并用空格分隔
- 如果别名是简单的单词(不包含空格或特殊字符),可以不用引号
- 如果别名包含空格、特殊字符(如 !@#$%^&*() 等)或保留关键字(如 SELECT、FROM 等),则必须使用引号
- 使用双引号定义别名,双引号是 SQL 标准中定义的方式
SELECT first_name name FROM users; SELECT column_name AS alias_name FROM table_name; SELECT first_name AS "First Name", last_name AS "Last Name" FROM employees; 返回结果中,first_name 列显示为 First Name,last_name 列显示为 Last Name
-
-
WHERE:可选,用于过滤数据- WHERE 子句不能直接使用聚合函数(如 SUM、AVG、COUNT 等)
- WHERE 子句在数据分组(GROUP BY)之前执行,而聚合函数的作用是基于分组后的结果进行计算。因此,在 WHERE 中直接使用聚合函数会导致逻辑冲突
-
GROUP BY:用于将数据按指定的列进行分组-
通常与聚合函数(如 COUNT、SUM、AVG、MAX、MIN 等)一起使用,以对每个分组进行计算
-
GROUP BY:关键字,表示按指定列分组
-
分组列:GROUP BY 子句中指定的列必须是 SELECT 子句中的列或聚合函数的参数
-
错误方式
-
SELECT 包含非聚合列且未分组
-
SELECT CustomerID, OrderDate,count(*) FROM Orders GROUP BY CustomerID; -- 错误:OrderDate 未包含在 GROUP BY 或聚合函数中 -
错误原因:OrderDate 在 SELECT 中但未参与分组或聚合,导致同一分组内可能存在多个不同的 OrderDate 值,无法确定显示哪个值
-
-
分组列未在 SELECT 中
-
SELECT CustomerID, SUM(Total) FROM Orders GROUP BY CustomerID, OrderDate; -- 错误:OrderDate 未在 SELECT 中列出 -
错误原因:GROUP BY 包含 OrderDate,但 SELECT 未选择该列,导致无法确定分组结果的显示方式(严格模式下会报错,宽松模式下不会报错但它可能不符合你的实际需求)
-
-
正确方式:
-
保持 GROUP BY 与 SELECT 列一致
-
SELECT CustomerID, OrderDate, SUM(Total) FROM Orders GROUP BY CustomerID, OrderDate; -- 正确:分组列与 SELECT 列一致
-
-
对非分组列使用聚合函数
-
SELECT CustomerID, MAX(OrderDate), SUM(Total) FROM Orders GROUP BY CustomerID; -- 正确:OrderDate 被聚合函数处理
-
-
-
-
分组顺序:GROUP BY 可以按多列分组,分组顺序会影响结果
-
分组顺序 1:GROUP BY Region, Year
-
结果按 Region 先分组,再按 Year 细分
-
(East, 2023), (East, 2024), (West, 2023)
-
-
分组顺序 2:GROUP BY Year, Region
-
结果按 Year 先分组,再按 Region 细分
-
(2023, East), (2023, West), (2024, East)
-
-
-
索引:为分组列创建索引,可以加快分组操作的速度
-
-
having:- HAVING 用于对分组后的结果进行过滤
- WHERE:在分组前过滤数据,HAVING:在分组后过滤数据
- GROUP BY 和 HAVING 通常一起使用,用于对分组后的数据进行过滤
- HAVING 子句中的条件可以包含聚合函数
-
ORDER BY:可选,用于对结果排序基本语法
SELECT column1, column2, ...FROM table_name [WHERE condition] ORDER BY column1 [ASC|DESC], column2 [ASC|DESC], ...;-
ASC:升序排序(默认值,可省略)
-
DESC:降序排序
-
按多个列对结果集进行排序。排序时,先按第一个列排序,如果第一个列的值相同,再按第二个列排序,以此类推
-
排序规则
- 数值类型:按数值大小排序。
- 字符串类型:按字典顺序排序(基于字符集和排序规则)。
- 日期类型:按日期先后排序。
- NULL 值:在升序排序中,NULL 值默认排在最前面;在降序排序中,NULL 值默认排在最后面
-
可以在 ORDER BY 子句中使用表达式或函数进行排序
-
如果查询结果中使用了别名,可以在 ORDER BY 子句中使用别名进行排序
SELECT first_name, last_name, salary * 12 AS annual_salary FROM employees ORDER BY annual_salary DESC; -
可以使用列的序号(在 SELECT 子句中的位置)进行排序,列序号从 1 开始
SELECT first_name, last_name, salary FROM employees ORDER BY 3 DESC; -
可以使用 NULLS FIRST 或 NULLS LAST 显式指定 NULL 值的排序位置(MySQL 8.0 及以上版本支持)
SELECT first_name, last_name, hire_date FROM employees ORDER BY hire_date DESC NULLS LAST; -
可以使用
CASE表达式实现复杂的排序逻辑SELECT first_name, last_name, salary FROM employees ORDER BY CASE WHEN salary < 3000 THEN 1 WHEN salary BETWEEN 3000 AND 5000 THEN 2 ELSE 3 END; 按工资范围排序:工资小于 3000 的排在最前面,工资在 3000 到 5000 之间的排在中间,其他排在最后 -
如果查询涉及多个表,可以在 ORDER BY 子句中使用表名或别名限定列名
SELECT e.first_name, e.last_name, d.department_name FROM employees e JOIN departments d ON e.department_id = d.department_id ORDER BY d.department_name ASC, e.salary DESC; -
如果排序的列上有索引,可以加快排序速度
-
使用 LIMIT 子句限制返回的行数,减少排序的数据量
-
-
LIMIT:可选,用于限制返回的行数基本语法
SELECT column1, column2, ... FROM table_name [WHERE condition] [ORDER BY column_name [ASC|DESC]] LIMIT number;- number:指定返回的行数
分页查询
- number:指定返回的行数。
- offset:指定跳过的行数
LIMIT number OFFSET offset; 跳过前 20 行,返回接下来的 10 行(即第 21 到 30 行) SELECT * FROM employees LIMIT 10 OFFSET 20;简写:
LIMIT offset, number是LIMIT number OFFSET offset的简写形式SELECT * FROM employees LIMIT 20, 10; 跳过前 20 行,返回接下来的 10 行(即第 21 到 30 行)-
LIMIT 通常与 ORDER BY 一起使用,以确保返回的行是按特定顺序排列的
-
LIMIT 可以与 WHERE 子句一起使用,以过滤数据并限制返回的行数
-
LIMIT 可以与聚合函数一起使用,以限制聚合结果的行数
SELECT department_id, COUNT(*) AS employee_count FROM employees GROUP BY department_id LIMIT 5; 返回员工数量最多的前 5 个部门 -
LIMIT 可以在子查询中使用,以限制子查询返回的行数

浙公网安备 33010602011771号