目录

一、基本查询

查询多个字段

设置别名

去除重复记录

二、条件查询 (WHERE)

三、聚合函数

四、分组查询 (GROUP BY)

五、排序查询 (ORDER BY)

六、分页查询 (LIMIT)

七、JOIN (连接查询)

八、执行顺序

总结:在 Python 中使用 SQL的DQL


一、基本查询

  1. 查询多个字段

    • 语法: SELECT column1, column2, ... FROM table_name
    • 作用: 从指定的表中选择一列或多列数据。
    • Python 示例:
      import sqlite3  # 以 SQLite 为例
      
      conn = sqlite3.connect('mydatabase.db')
      cursor = conn.cursor()
      
      # 查询 employees 表中的 id, name, department 字段
      cursor.execute("SELECT id, name, department FROM employees")
      results = cursor.fetchall()
      for row in results:
          print(row)
      
      conn.close()
      

  2. 设置别名

    • 语法: SELECT column_name AS alias_name FROM table_name
    • 作用: 给查询结果的列赋予一个临时的、更易理解的名称。
    • Python 示例:
      # 查询 name 列,并为其设置别名为 employee_name
      cursor.execute("SELECT name AS employee_name, department AS dept FROM employees")
      results = cursor.fetchall()
      for row in results:
          print(row)  # 输出如: ('Alice', 'Engineering')
          # 或者按别名访问 (如果数据库适配器支持): print(row['employee_name'])
      

  3. 去除重复记录

    • 语法: SELECT DISTINCT column1, column2, ... FROM table_name
    • 作用: 返回查询结果中指定列的唯一组合值。
    • Python 示例:
      # 查询 departments 表中所有唯一的部门名称
      cursor.execute("SELECT DISTINCT department FROM employees")
      unique_depts = cursor.fetchall()
      print(unique_depts)  # 输出如: [('Engineering',), ('Sales',), ('Marketing',)]
      

二、条件查询 (WHERE)

  1. 语法: SELECT ... FROM ... WHERE condition
  2. 条件 (condition):
    • 可以使用比较运算符:=, >, <, >=, <=, <>!=
    • 可以使用逻辑运算符:AND或&&, OR或||, NOT
    • 可以使用范围判断:BETWEEN ...(min) AND ...(max)
    • 可以使用集合判断:IN (value1, value2, ...)
    • 可以使用模糊匹配:LIKE 'pattern' (% 匹配任意字符序列,_ 匹配单个字符)
    • 可以判断空值:IS NULL, IS NOT NULL
  3. Python 示例:
    # 查询 Engineering 部门的所有员工
    cursor.execute("SELECT * FROM employees WHERE department = 'Engineering'")
    
    # 查询工资在 50000 到 70000 之间的员工 (使用 BETWEEN)
    cursor.execute("SELECT name, salary FROM employees WHERE salary BETWEEN 50000 AND 70000")
    
    # 查询名字以 'A' 开头的员工 (使用 LIKE)
    cursor.execute("SELECT name FROM employees WHERE name LIKE 'A%'")
    
    # 查询部门是 'Engineering' 或 'Sales' 的员工 (使用 IN)
    cursor.execute("SELECT * FROM employees WHERE department IN ('Engineering', 'Sales')")
    
    # 查询没有分配部门的员工 (IS NULL)
    cursor.execute("SELECT * FROM employees WHERE department IS NULL")
    
    # 使用参数化查询防止 SQL 注入 (推荐!!)
    dept_name = 'Engineering'
    cursor.execute("SELECT * FROM employees WHERE department = ?", (dept_name,))
    

三、聚合函数

  1. 介绍: 对一组值执行计算并返回单个值。常用于统计和汇总数据。
  2. 常见聚合函数:
    • COUNT():计算行数(或非 NULL 值的行数)。
    • SUM():计算数值列的总和。
    • AVG():计算数值列的平均值。
    • MAX():找出列中的最大值。
    • MIN():找出列中的最小值。
  3. 语法: SELECT AGG_FUNC(column_name) FROM table_name [WHERE ...]
    • 注意: 聚合函数在计算时会忽略 NULL 值。例如,COUNT(column_name) 统计的是该列非 NULL 的行数。
  4. Python 示例:
    # 计算 employees 表的总行数
    cursor.execute("SELECT COUNT(*) FROM employees")
    total_employees = cursor.fetchone()[0]
    print(f"Total employees: {total_employees}")
    
    # 计算 Engineering 部门的平均工资
    cursor.execute("SELECT AVG(salary) FROM employees WHERE department = 'Engineering'")
    avg_salary = cursor.fetchone()[0]
    print(f"Engineering Avg Salary: {avg_salary:.2f}")
    
    # 找出最高工资
    cursor.execute("SELECT MAX(salary) FROM employees")
    max_salary = cursor.fetchone()[0]
    print(f"Max Salary: {max_salary}")
    
    # 统计每个部门有多少非 NULL 的工资记录
    cursor.execute("SELECT department, COUNT(salary) FROM employees GROUP BY department")
    # 这个会结合分组查询,见下文
    

四、分组查询 (GROUP BY)

  1. 语法:
    SELECT column_name(s), AGG_FUNC(column_name)
    FROM table_name
    WHERE condition
    GROUP BY column_name(s)
    HAVING condition
    ORDER BY ...
    

  2. WHEREHAVING 的区别:
    • WHERE:在分组之前进行过滤。它作用于原始表的每一行WHERE 子句中不能使用聚合函数。
    • HAVING:在分组之后进行过滤。它作用于分组后的结果集HAVING 子句中可以使用聚合函数。
    • 执行顺序: WHERE > GROUP BY > 聚合函数计算 > HAVING > SELECT > ORDER BY > LIMIT
    • 注意: 分组之后,SELECT 子句中出现的字段,要么是聚合函数,要么是包含在 GROUP BY 子句中的字段。查询其他字段通常没有意义(除非该字段在功能上依赖于分组字段),具体行为取决于 SQL 模式。
  3. Python 示例:
    # 计算每个部门的平均工资 (GROUP BY 部门)
    cursor.execute("""
        SELECT department, AVG(salary) AS avg_salary
        FROM employees
        GROUP BY department
    """)
    dept_avgs = cursor.fetchall()
    for dept, avg in dept_avgs:
        print(f"{dept}: {avg:.2f}")
    
    # 计算员工数量超过 5 人的部门及其人数 (WHERE 过滤所有人, GROUP BY 部门, HAVING 过滤分组)
    cursor.execute("""
        SELECT department, COUNT(*) AS num_employees
        FROM employees
        WHERE active = 1  -- 假设有 active 字段表示在职状态
        GROUP BY department
        HAVING COUNT(*) > 5
    """)
    large_depts = cursor.fetchall()
    

五、排序查询 (ORDER BY)

  1. 语法: SELECT ... FROM ... ORDER BY column1 [ASC|DESC], column2 [ASC|DESC], ...
  2. 排序方式:
    • ASC:升序排列(默认)。
    • DESC:降序排列。
    • 可以按多个字段排序,优先级从左到右。
  3. Python 示例:
    # 按工资降序排列所有员工
    cursor.execute("SELECT name, salary FROM employees ORDER BY salary DESC")
    
    # 按部门升序排列,同一部门内按工资降序排列
    cursor.execute("SELECT name, department, salary FROM employees ORDER BY department ASC, salary DESC")
    

六、分页查询 (LIMIT)

  • 语法: SELECT ... FROM ... LIMIT offset, countSELECT ... FROM ... LIMIT count OFFSET offset
    • count:要返回的最大记录数。
    • offset:要跳过的记录数(从 0 开始计数)。第一页通常 offset 为 0。
  • 作用: 限制查询结果返回的行数,常用于实现分页功能。
  • Python 示例:
    # 获取第一页数据 (前 10 条记录)
    page = 1
    page_size = 10
    offset = (page - 1) * page_size
    
    # 写法 1: LIMIT offset, count
    cursor.execute("SELECT * FROM employees ORDER BY id LIMIT ?, ?", (offset, page_size))
    
    # 写法 2: LIMIT count OFFSET offset
    cursor.execute("SELECT * FROM employees ORDER BY id LIMIT ? OFFSET ?", (page_size, offset))
    
    page1_results = cursor.fetchall()
    
    # 获取第二页数据
    page = 2
    offset = (page - 1) * page_size
    cursor.execute("SELECT * FROM employees ORDER BY id LIMIT ? OFFSET ?", (page_size, offset))
    page2_results = cursor.fetchall()
    

七、JOIN (连接查询)

  • 作用: 用于基于两个或多个表之间的相关列(通常是外键关系)组合行。
  • 常见类型:
    • INNER JOIN (或 JOIN): 返回两个表中匹配的行。
    • LEFT (OUTER) JOIN: 返回左表的所有行,即使右表没有匹配。右表无匹配则为 NULL。
    • RIGHT (OUTER) JOIN: 返回右表的所有行,即使左表没有匹配。左表无匹配则为 NULL。(SQLite 不支持 RIGHT JOIN)
    • FULL (OUTER) JOIN: 返回两个表的所有行。不匹配的填充 NULL。(SQLite 不支持 FULL JOIN)
  • 语法:
    SELECT table1.column1, table2.column2, ...
    FROM table1
    [INNER | LEFT | RIGHT | FULL] JOIN table2
    ON table1.common_column = table2.common_column
    [WHERE ...]
    [GROUP BY ...]
    [HAVING ...]
    [ORDER BY ...]
    [LIMIT ...]
    

  • Python 示例 (INNER JOIN):
    # 假设有 employees 表和 departments 表 (employees.department_id = departments.id)
    cursor.execute("""
        SELECT e.name, d.department_name AS dept_name, e.salary
        FROM employees e
        INNER JOIN departments d ON e.department_id = d.id
        WHERE e.salary > 60000
        ORDER BY e.salary DESC
    """)
    high_earners = cursor.fetchall()
    

八、执行顺序

SQL 查询语句的关键字并非按照书写的顺序执行。理解执行顺序对于编写正确高效的查询和理解结果至关重要:

  1. FROM & JOIN: 确定数据的来源表,并进行连接操作。
  2. WHERE: 根据条件过滤原始表的行。此时聚合函数不可用。
  3. GROUP BY: 将过滤后的行进行分组。
  4. 计算 聚合函数 (COUNT, SUM, AVG 等): 对每个分组进行计算。
  5. HAVING: 根据条件过滤分组后的结果集。此时可以使用聚合函数结果作为条件。
  6. SELECT: 选择最终要显示的列或表达式。此时可以给列设置别名。
  7. DISTINCT: 去除重复的行。
  8. ORDER BY: 对最终结果集进行排序。
  9. LIMIT / OFFSET: 限制返回的行数,实现分页。

总结:在 Python 中使用 SQL的DQL

在 Python 中执行 SQL 查询,通常遵循以下步骤:

  1. 导入数据库库:sqlite3, psycopg2 (PostgreSQL), PyMySQL/mysql-connector-python (MySQL), pyodbc (ODBC) 等。
  2. 建立连接: 使用库提供的函数连接到数据库文件或服务器。
  3. 创建游标: 通过连接对象创建游标 (cursor),用于执行 SQL 语句。
  4. 编写 SQL 语句: 按照上述 DQL 语法编写查询语句。强烈推荐使用参数化查询 (?%s 占位符) 来传递变量值,以防止 SQL 注入攻击。
  5. 执行查询: 使用游标的 execute() 方法执行 SQL 语句。如果是带参数的查询,将参数作为元组传递给 execute 的第二个参数。
  6. 获取结果:
    • fetchone(): 获取下一行。
    • fetchmany(size): 获取指定数量的行。
    • fetchall(): 获取所有剩余行。
  7. 处理结果: 对获取到的结果集(通常是元组列表或字典列表)进行迭代和处理。
  8. 关闭游标和连接: 使用 close() 方法释放资源。

更多推荐