MySQL8创建测试数据,日常练习06【DQL数据查询语句001】

文章目录

  • MySQL 8 DQL数据查询语句详解:从入门到高级(15个实例)
    • 一、入门级:基础查询与过滤
      • 实例1:查询所有列(SELECT *)
      • 实例2:查询指定列(SELECT 列名)
      • 实例3:条件过滤(WHERE子句)
      • 实例4:模糊查询(LIKE)
      • 实例5:去重查询(DISTINCT)
    • 二、进阶级:聚合与分组
      • 实例6:聚合函数(MAX/MIN/AVG/SUM/COUNT)
      • 实例7:分组统计(GROUP BY)
      • 实例8:分组后过滤(HAVING子句)
      • 实例9:多表连接(INNER JOIN)
      • 实例10:左连接(LEFT JOIN)
    • 三、高级:复杂查询与性能优化
      • 实例11:子查询(嵌套查询)
      • 实例12:窗口函数(OVER/PARTITION BY)
      • 实例13:公共表表达式(CTE,WITH子句)
      • 实例14:全文索引查询(MATCH...AGAINST)
      • 实例15:分页查询(LIMIT/OFFSET)
    • 总结:DQL核心要点

MySQL 8 DQL数据查询语句详解:从入门到高级(15个实例)

DQL(Data Query Language,数据查询语言)是SQL中最核心的部分,用于从数据库中检索数据。本文以MySQL 8为背景,结合员工表(employees)部门表(departments)薪资表(salaries)等业务场景,分入门→进阶→高级三个层级,通过15个实例详细讲解DQL的核心语法和应用。


一、入门级:基础查询与过滤

实例1:查询所有列(SELECT *)

-- 从employees表中查询所有列的所有记录
SELECT * FROM employees;

讲解

  • SELECT * 表示选择表中所有列(*是通配符)。
  • FROM employees 指定数据来源表为employees
  • 适用场景:快速查看表结构或临时调试,但生产环境中不建议使用(可能泄露敏感字段)。

实例2:查询指定列(SELECT 列名)

-- 查询员工姓名(first_name)、邮箱(email)和入职日期(hire_date)
SELECT first_name, email, hire_date 
FROM employees;

讲解

  • 显式指定需要的列,避免冗余数据传输。
  • 适用场景:需要特定字段的业务报表(如导出员工联系方式)。

实例3:条件过滤(WHERE子句)

-- 查询薪资大于80000且部门ID为3的员工
SELECT first_name, salary, department_id 
FROM employees 
WHERE salary > 80000 AND department_id = 3;

讲解

  • WHERE 子句用于筛选满足条件的记录,支持逻辑运算符(AND/OR/NOT)和比较运算符(>/</=/IN/BETWEEN等)。
  • 示例中AND表示两个条件需同时满足(薪资>80000 部门ID=3)。

实例4:模糊查询(LIKE)

-- 查询姓名以"John"开头的员工(如John Doe、Johnny)
SELECT first_name, last_name 
FROM employees 
WHERE first_name LIKE 'John%';

讲解

  • LIKE 用于字符串模糊匹配,% 是通配符(表示任意字符序列,包括空)。
  • 类似用法:LIKE '%Doe'(以"Doe"结尾)、LIKE '%Ann%'(包含"Ann")。

实例5:去重查询(DISTINCT)

-- 查询所有不同的部门ID(去除重复值)
SELECT DISTINCT department_id 
FROM employees;

讲解

  • DISTINCT 关键字用于去除结果中的重复行。
  • 适用场景:统计唯一值(如部门数量、客户来源地)。

二、进阶级:聚合与分组

实例6:聚合函数(MAX/MIN/AVG/SUM/COUNT)

-- 统计全公司最高工资、最低工资、平均工资、总工资和员工总数
SELECT 
    MAX(salary) AS max_salary,
    MIN(salary) AS min_salary,
    AVG(salary) AS avg_salary,
    SUM(salary) AS total_salary,
    COUNT(*) AS employee_count
FROM employees;

讲解

  • 聚合函数用于对一组值进行计算,返回单一值:
    • MAX():最大值(忽略NULL)。
    • MIN():最小值(忽略NULL)。
    • AVG():平均值(自动跳过NULL)。
    • SUM():总和(NULL视为0)。
    • COUNT(*):统计所有行(包括NULL);COUNT(column):统计非NULL的列值。

实例7:分组统计(GROUP BY)

-- 按部门分组,统计各部门的平均工资和员工数
SELECT 
    department_id,
    AVG(salary) AS dept_avg_salary,
    COUNT(*) AS dept_employee_count
FROM employees 
GROUP BY department_id;

讲解

  • GROUP BY department_id 将数据按department_id分组,每组内的聚合函数(AVG/COUNT)单独计算。
  • 执行逻辑:先按部门分组,再对每组计算平均工资和人数。

实例8:分组后过滤(HAVING子句)

-- 查询平均工资超过70000的部门
SELECT 
    department_id,
    AVG(salary) AS dept_avg_salary
FROM employees 
GROUP BY department_id
HAVING dept_avg_salary > 70000;

讲解

  • HAVING 用于对分组后的结果过滤,与WHERE的区别:
    • WHERE 过滤行级数据(分组前)。
    • HAVING 过滤分组后的聚合结果(分组后)。

实例9:多表连接(INNER JOIN)

-- 查询员工姓名、部门名称(需关联departments表)
SELECT 
    e.first_name, 
    e.last_name, 
    d.department_name
FROM employees e
INNER JOIN departments d 
    ON e.department_id = d.department_id;

讲解

  • INNER JOIN(内连接)返回两个表中满足连接条件的记录(e.department_id = d.department_id)。
  • 别名e(employees)和d(departments)简化语句,提高可读性。

实例10:左连接(LEFT JOIN)

-- 查询所有员工姓名,即使无对应部门(部门名称显示NULL)
SELECT 
    e.first_name, 
    e.last_name, 
    d.department_name
FROM employees e
LEFT JOIN departments d 
    ON e.department_id = d.department_id;

讲解

  • LEFT JOIN(左连接)保留左表(employees)的所有记录,右表(departments)无匹配时字段为NULL
  • 类似:RIGHT JOIN(右连接,保留右表所有记录)、FULL OUTER JOIN(全外连接,MySQL 8不直接支持,需用UNION模拟)。

三、高级:复杂查询与性能优化

实例11:子查询(嵌套查询)

-- 查询工资高于平均工资的员工姓名
SELECT first_name, last_name, salary
FROM employees
WHERE salary > (SELECT AVG(salary) FROM employees);

讲解

  • 子查询(SELECT AVG(salary) FROM employees)先计算全公司平均工资,主查询再筛选高于该值的员工。
  • 子查询类型:标量子查询(返回单个值)、行子查询(返回一行多列)、表子查询(返回多行多列)。

实例12:窗口函数(OVER/PARTITION BY)

-- 查询员工姓名、部门ID、工资,以及部门内工资排名
SELECT 
    first_name,
    department_id,
    salary,
    RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) AS dept_salary_rank
FROM employees;

讲解

  • 窗口函数RANK()用于计算分组内的排名(PARTITION BY department_id按部门分组,ORDER BY salary DESC按工资降序)。
  • 类似函数:DENSE_RANK()(密集排名,无间隔)、ROW_NUMBER()(行号,无重复)。

实例13:公共表表达式(CTE,WITH子句)

-- 使用CTE临时存储各部门平均工资,再查询高薪部门
WITH dept_avg AS (
    SELECT 
        department_id,
        AVG(salary) AS avg_salary
    FROM employees 
    GROUP BY department_id
)
SELECT department_id, avg_salary 
FROM dept_avg 
WHERE avg_salary > 75000;

讲解

  • WITH dept_avg AS (...) 定义一个临时结果集(CTE),后续可直接引用。
  • 优势:提高可读性,避免重复计算(尤其复杂查询中)。

实例14:全文索引查询(MATCH…AGAINST)

-- 查询包含"database"或"optimization"关键词的简历(假设employees表有resume_text字段)
SELECT first_name, last_name, resume_text
FROM employees
WHERE MATCH(resume_text) AGAINST('database optimization' IN NATURAL LANGUAGE MODE);

讲解

  • MySQL 8支持全文索引(FULLTEXT),MATCH...AGAINST用于高效搜索文本内容。
  • 适用场景:简历筛选、文章检索等需要文本匹配的业务。

实例15:分页查询(LIMIT/OFFSET)

-- 查询第3页数据(每页10条,跳过前20条)
SELECT * FROM employees
ORDER BY hire_date DESC  -- 按入职时间倒序排列(确保分页顺序稳定)
LIMIT 10 OFFSET 20;      -- 跳过20条,取10条

讲解

  • LIMIT 10:限制返回10条记录。
  • OFFSET 20:跳过前20条记录(适用于分页)。
  • 注意:OFFSET过大时性能下降(可通过覆盖索引优化)。

总结:DQL核心要点

层级 核心功能 典型语句 应用场景
入门级 基础数据检索与过滤 SELECTWHERELIKEDISTINCT 快速查看数据、简单业务报表
进阶级 聚合统计与多表关联 GROUP BYHAVINGJOIN 部门统计、跨表数据整合
高级 复杂逻辑与性能优化 窗口函数、CTE、全文索引、分页 数据分析、大数据量查询、文本检索

掌握以上15个实例后,可应对90%以上的业务查询需求。实际使用中需注意:

  • 避免SELECT *,显式指定列以提高性能。
  • 多表连接时优先使用INNER JOIN,减少冗余数据。
  • 分页查询OFFSET过大时,改用WHERE id > last_id(基于索引的范围查询)优化性能。

你可能感兴趣的:(#,002-SQL基础篇,MySQL)