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];
  1. DISTINCT:可选关键字,用于去除查询结果中的重复行

    • DISTINCT 作用于所有选择的列:如果选择了多列,DISTINCT 会基于这些列的组合值去重
    • DISTINCT 的性能:去重操作需要对结果集进行排序和比较,可能会影响查询性能,尤其是在大数据集上
    • DISTINCT 与 NULL:如果列中包含 NULL 值,DISTINCT 会将所有 NULL 视为相同的值,只保留一个 NULL
    • DISTINCT 可以与聚合函数一起使用,例如 COUNT(DISTINCT column_name),用于统计某列的唯一值数量
  2. SELECT:指定要查询的列

  3. 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
      
  4. WHERE:可选,用于过滤数据

    • WHERE 子句不能直接使用聚合函数(如 SUM、AVG、COUNT 等)
    • WHERE 子句在数据分组(GROUP BY)之前执行,而聚合函数的作用是基于分组后的结果进行计算。因此,在 WHERE 中直接使用聚合函数会导致逻辑冲突
  5. 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)
          
    • 索引:为分组列创建索引,可以加快分组操作的速度

  6. having

    • HAVING 用于对分组后的结果进行过滤
    • WHERE:在分组前过滤数据,HAVING:在分组后过滤数据
    • GROUP BY 和 HAVING 通常一起使用,用于对分组后的数据进行过滤
    • HAVING 子句中的条件可以包含聚合函数
  7. 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 子句限制返回的行数,减少排序的数据量

  8. 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, numberLIMIT 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 可以在子查询中使用,以限制子查询返回的行数

posted @ 2025-03-17 21:31  QAQ001  阅读(54)  评论(0)    收藏  举报