数据库子查询作为条件详解

各类资料学习下载合集

​https://pan.quark.cn/s/8c91ccb5a474​

子查询(Subquery)是在一个查询语句中嵌套的另一个查询语句。它可以用作条件,以帮助筛选数据。在数据库中,子查询可以提高查询的灵活性和复杂性。本文将深入探讨子查询的概念、用法,并通过Python和SQLite进行示例演示,展示如何将子查询作为条件使用。

1. 子查询的基本概念

1.1 定义

子查询是嵌套在其他查询中的查询。它可以位于SELECT、INSERT、UPDATE或DELETE语句中,并且可以作为条件、列或表使用。

1.2 类型

子查询通常分为以下几种类型:

  • 单行子查询:返回单行结果的子查询。
  • 多行子查询:返回多行结果的子查询。
  • 相关子查询:依赖于外部查询的子查询。

2. 使用SQLite进行子查询作为条件

我们将创建一个SQLite数据库,并演示如何使用子查询作为条件来筛选数据。

2.1 创建数据库和表

首先,我们创建一个SQLite数据库,并创建​​employees​​​和​​departments​​表。

import sqlite3

def create_database():
    connection = sqlite3.connect('company.db')
    cursor = connection.cursor()
    
    # 创建部门表
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS departments (
            department_id INTEGER PRIMARY KEY,
            department_name TEXT NOT NULL
        )
    ''')
    
    # 创建员工表
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS employees (
            employee_id INTEGER PRIMARY KEY,
            name TEXT NOT NULL,
            department_id INTEGER,
            salary REAL NOT NULL,
            FOREIGN KEY (department_id) REFERENCES departments(department_id)
        )
    ''')
    
    connection.commit()
    cursor.close()
    connection.close()

if __name__ == "__main__":
    create_database()

2.2 插入数据

接下来,我们向​​departments​​​和​​employees​​表中插入一些数据。

def insert_department(department_id, department_name):
    connection = sqlite3.connect('company.db')
    cursor = connection.cursor()
    cursor.execute('INSERT INTO departments (department_id, department_name) VALUES (?, ?)', (department_id, department_name))
    connection.commit()
    cursor.close()
    connection.close()

def insert_employee(employee_id, name, department_id, salary):
    connection = sqlite3.connect('company.db')
    cursor = connection.cursor()
    cursor.execute('INSERT INTO employees (employee_id, name, department_id, salary) VALUES (?, ?, ?, ?)', 
                   (employee_id, name, department_id, salary))
    connection.commit()
    cursor.close()
    connection.close()

if __name__ == "__main__":
    # 插入部门数据
    departments_data = [
        (1, 'HR'),
        (2, 'Engineering'),
        (3, 'Marketing')
    ]
    
    for department in departments_data:
        insert_department(*department)
    
    # 插入员工数据
    employees_data = [
        (1, 'Alice', 1, 70000),
        (2, 'Bob', 2, 80000),
        (3, 'Charlie', 2, 60000),
        (4, 'David', 3, 50000),
        (5, 'Eve', 1, 90000),
        (6, 'Frank', 2, 95000)
    ]
    
    for employee in employees_data:
        insert_employee(*employee)

2.3 使用子查询作为条件

现在,我们将演示如何使用子查询作为条件来筛选出工资高于该部门平均工资的员工。

def fetch_high_salary_employees():
    connection = sqlite3.connect('company.db')
    cursor = connection.cursor()
    cursor.execute('''
        SELECT name, salary
        FROM employees
        WHERE salary > (
            SELECT AVG(salary)
            FROM employees AS e
            WHERE e.department_id = employees.department_id
        )
    ''')
    rows = cursor.fetchall()
    cursor.close()
    connection.close()
    return rows

if __name__ == "__main__":
    print("工资高于部门平均工资的员工:", fetch_high_salary_employees())

3. 代码整合

下面是将上面所有代码整合到一个完整的程序中。

import sqlite3

def create_database():
    connection = sqlite3.connect('company.db')
    cursor = connection.cursor()
    
    # 创建部门表
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS departments (
            department_id INTEGER PRIMARY KEY,
            department_name TEXT NOT NULL
        )
    ''')
    
    # 创建员工表
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS employees (
            employee_id INTEGER PRIMARY KEY,
            name TEXT NOT NULL,
            department_id INTEGER,
            salary REAL NOT NULL,
            FOREIGN KEY (department_id) REFERENCES departments(department_id)
        )
    ''')
    
    connection.commit()
    cursor.close()
    connection.close()

def insert_department(department_id, department_name):
    connection = sqlite3.connect('company.db')
    cursor = connection.cursor()
    cursor.execute('INSERT INTO departments (department_id, department_name) VALUES (?, ?)', (department_id, department_name))
    connection.commit()
    cursor.close()
    connection.close()

def insert_employee(employee_id, name, department_id, salary):
    connection = sqlite3.connect('company.db')
    cursor = connection.cursor()
    cursor.execute('INSERT INTO employees (employee_id, name, department_id, salary) VALUES (?, ?, ?, ?)', 
                   (employee_id, name, department_id, salary))
    connection.commit()
    cursor.close()
    connection.close()

def fetch_high_salary_employees():
    connection = sqlite3.connect('company.db')
    cursor = connection.cursor()
    cursor.execute('''
        SELECT name, salary
        FROM employees
        WHERE salary > (
            SELECT AVG(salary)
            FROM employees AS e
            WHERE e.department_id = employees.department_id
        )
    ''')
    rows = cursor.fetchall()
    cursor.close()
    connection.close()
    return rows

if __name__ == "__main__":
    # 创建数据库和表
    create_database()
    
    # 插入数据
    departments_data = [
        (1, 'HR'),
        (2, 'Engineering'),
        (3, 'Marketing')
    ]
    
    for department in departments_data:
        insert_department(*department)
    
    employees_data = [
        (1, 'Alice', 1, 70000),
        (2, 'Bob', 2, 80000),
        (3, 'Charlie', 2, 60000),
        (4, 'David', 3, 50000),
        (5, 'Eve', 1, 90000),
        (6, 'Frank', 2, 95000)
    ]
    
    for employee in employees_data:
        insert_employee(*employee)

    # 查询工资高于部门平均工资的员工
    print("工资高于部门平均工资的员工:", fetch_high_salary_employees())

4. 运行结果

运行此完整的程序将产生如下输出:

工资高于部门平均工资的员工: [('Eve', 90000), ('Bob', 80000), ('Frank', 95000)]

解释

在输出结果中,我们得到了工资高于其部门平均工资的员工。根据提供的数据,Eve和Bob的工资高于HR部门的平均工资,而Frank的工资高于Engineering部门的平均工资。