SQL经典常用查询语句

1. 基础查询语句

1.1 查询表中所有数据

在SQL中,查询表中所有数据是最基本的操作之一。通过使用SELECT * FROM table_name;语句,可以获取指定表中的所有记录和列。例如,假设有一个名为employees的表,包含员工的基本信息,执行以下语句:

SELECT * FROM employees;

将返回employees表中的所有数据,包括员工的姓名、职位、工资等所有字段。这种查询方式适用于需要查看表中完整数据的情况,但需要注意,当表中数据量较大时,返回的结果集可能会非常庞大,对性能有一定影响。

1.2 查询指定列数据

在实际应用中,通常只需要查询表中的部分列,而不是所有列。通过指定列名,可以更高效地获取所需数据。例如,如果只想查询employees表中员工的姓名和工资,可以使用以下语句:

SELECT name, salary FROM employees;

这种方式不仅可以减少数据传输量,还能提高查询效率,特别是在处理大型表时。此外,还可以通过AS关键字为列名设置别名,使结果更易于理解。例如:

SELECT name AS employee_name, salary AS employee_salary FROM employees;

这将使查询结果中的列名更具可读性。

1.3 查询满足条件的数据

在SQL中,WHERE子句用于筛选满足特定条件的记录。这是数据查询中非常重要的功能,可以精确地获取所需数据。例如,假设需要查询工资大于5000的员工信息,可以使用以下语句:

SELECT * FROM employees WHERE salary > 5000;

此外,还可以使用多种条件运算符,如=<><=>=<>(不等于)等,以及逻辑运算符ANDORNOT来组合复杂的条件。例如,查询工资大于5000且职位为“经理”的员工信息:

SELECT * FROM employees WHERE salary > 5000 AND position = '经理';

这种条件查询方式在实际应用中非常灵活,可以根据具体需求精确地筛选数据。

2. 条件查询语句

2.1 单条件查询

单条件查询是 SQL 查询中最为基础且常见的类型,它通过一个简单的条件筛选数据,能够快速定位到符合特定要求的记录。在实际应用中,单条件查询的使用频率非常高,尤其是在数据筛选和初步分析阶段。

  • 基本语法SELECT column_name(s) FROM table_name WHERE condition;
  • 示例:假设有一个 employees 表,包含员工的姓名、职位、工资等信息,如果需要查询工资大于 5000 的员工信息,可以使用以下语句:
    SELECT * FROM employees WHERE salary > 5000;
    
    这条语句会返回所有工资大于 5000 的员工记录,包括他们的姓名、职位、工资等所有字段。
  • 性能分析:单条件查询的性能主要取决于条件的复杂度以及表的索引情况。如果表中存在针对查询条件的索引(如在 salary 字段上有索引),查询效率会显著提高。例如,在一个包含 100 万条记录的 employees 表中,如果没有索引,查询可能需要扫描整个表,耗时较长;而如果在 salary 字段上有索引,查询时间可以缩短到毫秒级别。
  • 应用场景:单条件查询适用于简单的数据筛选场景,如查询某个特定时间段内的数据、某个特定状态的数据等。例如,查询最近一个月内注册的用户:
    SELECT * FROM users WHERE registration_date >= DATE_SUB(CURDATE(), INTERVAL 1 MONTH);
    

2.2 多条件查询

多条件查询允许通过多个条件组合来筛选数据,能够更精确地定位到符合多个要求的记录。通过逻辑运算符 ANDORNOT,可以实现复杂的条件组合,满足多样化的数据查询需求。

  • 基本语法
    • 使用 ANDSELECT column_name(s) FROM table_name WHERE condition1 AND condition2;
    • 使用 ORSELECT column_name(s) FROM table_name WHERE condition1 OR condition2;
    • 使用 NOTSELECT column_name(s) FROM table_name WHERE NOT condition;
  • 示例
    • 查询工资大于 5000 且职位为“经理”的员工信息:
      SELECT * FROM employees WHERE salary > 5000 AND position = '经理';
      
    • 查询工资大于 5000 或职位为“经理”的员工信息:
      SELECT * FROM employees WHERE salary > 5000 OR position = '经理';
      
    • 查询工资不大于 5000 的员工信息:
      SELECT * FROM employees WHERE NOT salary > 5000;
      
  • 性能分析:多条件查询的性能同样取决于条件的复杂度和索引情况。如果多个条件都涉及索引字段,查询效率会更高。例如,在一个包含 100 万条记录的 employees 表中,如果 salaryposition 字段都有索引,使用 AND 条件的查询可以快速定位到符合条件的记录,查询时间通常在毫秒级别。然而,如果条件涉及非索引字段,或者使用了复杂的逻辑运算符(如多个 OR),查询性能可能会下降。
  • 应用场景:多条件查询适用于需要同时满足多个条件的复杂数据筛选场景。例如,查询某个部门中工资大于 5000 且入职时间在一年内的员工:
    SELECT * FROM employees WHERE department = '销售部' AND salary > 5000 AND hire_date >= DATE_SUB(CURDATE(), INTERVAL 1 YEAR);
    

2.3 模糊查询

模糊查询用于查找符合某种模式的记录,通常通过 LIKE 运算符实现。它允许使用通配符(如 %_)来匹配不确定的字符,能够灵活地筛选出符合条件的记录。

  • 基本语法SELECT column_name(s) FROM table_name WHERE column_name LIKE pattern;
  • 通配符
    • %:匹配任意数量的字符(包括零个字符)。
    • _:匹配任意单个字符。
  • 示例
    • 查询姓名以“张”开头的员工信息:
      SELECT * FROM employees WHERE name LIKE '张%';
      
    • 查询姓名为两个字且第二个字为“伟”的员工信息:
      SELECT * FROM employees WHERE name LIKE '_伟';
      
    • 查询姓名中包含“明”的员工信息:
      SELECT * FROM employees WHERE name LIKE '%明%';
      
  • 性能分析:模糊查询的性能通常比精确查询要低,尤其是当使用前导通配符(如 % 在模式的开头)时。这是因为数据库需要扫描整个字段来匹配模式,无法有效利用索引。例如,在一个包含 100 万条记录的 employees 表中,使用 LIKE '张%' 可以利用索引,查询时间较快;而使用 LIKE '%张' 则需要全表扫描,查询时间会显著增加。
  • 应用场景:模糊查询适用于需要查找符合某种模式的记录的场景,如搜索功能、数据分类等。例如,查询所有以“科技”结尾的公司名称:
    SELECT * FROM companies WHERE company_name LIKE '%科技';
    

3. 聚合函数查询语句

聚合函数是 SQL 中用于对数据进行统计分析的重要工具,能够对一组值进行计算并返回单个值。以下将从计算总和、最大值和最小值三个常见场景展开介绍。

3.1 计算总和

在数据分析中,计算总和是一种常见的需求,例如计算销售额、工资总额等。SQL 提供了 SUM 函数来实现这一功能。

  • 基本语法SELECT SUM(column_name) FROM table_name;
  • 示例:假设有一个 sales 表,包含销售订单的金额信息,如果需要计算所有订单的总销售额,可以使用以下语句:
    SELECT SUM(amount) AS total_sales FROM sales;
    
    这条语句会返回所有订单金额的总和,并将其命名为 total_sales
  • 性能分析SUM 函数的性能主要取决于表的大小和数据的分布情况。在大数据量的情况下,查询可能会相对较慢。但如果表中存在针对 amount 字段的索引,查询效率会有所提升。例如,在一个包含 100 万条记录的 sales 表中,使用 SUM 函数计算总销售额,查询时间通常在秒级别。
  • 应用场景:计算总和适用于需要对某一列数据进行累加的场景,如统计公司各部门的工资总额、计算产品库存总量等。例如,计算每个部门的工资总额:
    SELECT department, SUM(salary) AS total_salary FROM employees GROUP BY department;
    

3.2 计算最大值

在实际应用中,经常需要找出某一列中的最大值,例如最高工资、最高销售额等。SQL 提供了 MAX 函数来实现这一功能。

  • 基本语法SELECT MAX(column_name) FROM table_name;
  • 示例:假设有一个 employees 表,包含员工的工资信息,如果需要查询最高工资,可以使用以下语句:
    SELECT MAX(salary) AS max_salary FROM employees;
    
    这条语句会返回员工工资中的最大值,并将其命名为 max_salary
  • 性能分析MAX 函数的性能同样取决于表的大小和数据的分布情况。如果表中存在针对查询列的索引,查询效率会更高。例如,在一个包含 100 万条记录的 employees 表中,如果 salary 字段上有索引,使用 MAX 函数查询最高工资,查询时间通常在毫秒级别。
  • 应用场景:计算最大值适用于需要找出某一列中最大值的场景,如确定最高销售额、最高评分等。例如,查询每个部门的最高工资:
    SELECT department, MAX(salary) AS max_salary FROM employees GROUP BY department;
    

3.3 计算最小值

与计算最大值类似,计算最小值也是数据分析中的常见需求,例如最低工资、最低价格等。SQL 提供了 MIN 函数来实现这一功能。

  • 基本语法SELECT MIN(column_name) FROM table_name;
  • 示例:假设有一个 products 表,包含产品的价格信息,如果需要查询最低价格,可以使用以下语句:
    SELECT MIN(price) AS min_price FROM products;
    
    这条语句会返回产品价格中的最小值,并将其命名为 min_price
  • 性能分析MIN 函数的性能表现与 MAX 函数类似,主要取决于表的大小和数据的分布情况。如果表中存在针对查询列的索引,查询效率会显著提高。例如,在一个包含 100 万条记录的 products 表中,如果 price 字段上有索引,使用 MIN 函数查询最低价格,查询时间通常在毫秒级别。
  • 应用场景:计算最小值适用于需要找出某一列中最小值的场景,如确定最低工资、最低库存量等。例如,查询每个部门的最低工资:
    SELECT department, MIN(salary) AS min_salary FROM employees GROUP BY department;
    

4. 分组查询语句

4.1 按单一字段分组

在 SQL 中,GROUP BY 子句用于将数据按照某个字段进行分组,以便对每个分组进行聚合计算。按单一字段分组是最基本的分组方式,能够帮助我们快速了解数据在某个维度上的分布情况。

  • 基本语法SELECT column_name, aggregate_function(column_name) FROM table_name GROUP BY column_name;
  • 示例:假设有一个 employees 表,包含员工的部门和工资信息,如果需要计算每个部门的平均工资,可以使用以下语句:
    SELECT department, AVG(salary) AS avg_salary FROM employees GROUP BY department;
    
    这条语句会将员工按照部门分组,并计算每个部门的平均工资。
  • 性能分析:按单一字段分组的性能主要取决于表的大小和分组字段的索引情况。如果分组字段上有索引,查询效率会更高。例如,在一个包含 100 万条记录的 employees 表中,如果 department 字段上有索引,使用 GROUP BY 分组查询,查询时间通常在秒级别。
  • 应用场景:按单一字段分组适用于需要对数据进行简单分组统计的场景,如统计每个产品的销售数量、每个客户的订单数量等。例如,统计每个产品的销售数量:
    SELECT product_id, COUNT(*) AS sales_count FROM orders GROUP BY product_id;
    

4.2 按多个字段分组

按多个字段分组可以同时根据多个维度对数据进行分组,能够更细致地分析数据的分布情况。这种方式在实际应用中非常灵活,可以满足复杂的统计需求。

  • 基本语法SELECT column_name1, column_name2, aggregate_function(column_name) FROM table_name GROUP BY column_name1, column_name2;
  • 示例:假设有一个 sales 表,包含销售订单的日期、产品和金额信息,如果需要计算每个日期和每个产品的总销售额,可以使用以下语句:
    SELECT sale_date, product_id, SUM(amount) AS total_sales FROM sales GROUP BY sale_date, product_id;
    
    这条语句会将销售订单按照日期和产品分组,并计算每个分组的总销售额。
  • 性能分析:按多个字段分组的性能同样取决于表的大小和分组字段的索引情况。如果多个分组字段都有索引,查询效率会更高。例如,在一个包含 100 万条记录的 sales 表中,如果 sale_dateproduct_id 字段都有索引,使用 GROUP BY 分组查询,查询时间通常在秒级别。
  • 应用场景:按多个字段分组适用于需要同时根据多个维度进行数据统计的场景,如统计每个部门每个职位的员工数量、每个地区每个产品的销售额等。例如,统计每个部门每个职位的员工数量:
    SELECT department, position, COUNT(*) AS employee_count FROM employees GROUP BY department, position;
    

4.3 分组后筛选

在分组查询的基础上,使用 HAVING 子句可以对分组后的结果进行筛选,以便进一步过滤数据。HAVING 子句的作用类似于 WHERE 子句,但它用于筛选分组后的聚合结果,而不是单条记录。

  • 基本语法SELECT column_name, aggregate_function(column_name) FROM table_name GROUP BY column_name HAVING condition;
  • 示例:假设有一个 employees 表,包含员工的部门和工资信息,如果需要查询平均工资大于 5000 的部门,可以使用以下语句:
    SELECT department, AVG(salary) AS avg_salary FROM employees GROUP BY department HAVING AVG(salary) > 5000;
    
    这条语句会将员工按照部门分组,计算每个部门的平均工资,并筛选出平均工资大于 5000 的部门。
  • 性能分析:分组后筛选的性能主要取决于分组查询的效率和筛选条件的复杂度。如果分组字段上有索引,查询效率会更高。例如,在一个包含 100 万条记录的 employees 表中,如果 department 字段上有索引,使用 GROUP BYHAVING 子句进行筛选,查询时间通常在秒级别。
  • 应用场景:分组后筛选适用于需要对分组结果进行进一步筛选的场景,如筛选销售额超过某个阈值的产品、筛选员工数量超过某个阈值的部门等。例如,筛选销售额超过 10000 的产品:
    SELECT product_id, SUM(amount) AS total_sales FROM sales GROUP BY product_id HAVING SUM(amount) > 10000;
    

5. 排序查询语句

5.1 单字段排序

在 SQL 中,ORDER BY 子句用于对查询结果按照指定字段进行排序,这是数据展示和分析中常用的功能之一。单字段排序是最基本的排序方式,能够帮助我们快速了解数据在某个维度上的顺序关系。

  • 基本语法SELECT column_name(s) FROM table_name ORDER BY column_name [ASC|DESC];
    • ASC 表示升序排序(默认值),DESC 表示降序排序。
  • 示例:假设有一个 employees 表,包含员工的姓名和工资信息,如果需要按照工资升序排序,可以使用以下语句:
    SELECT name, salary FROM employees ORDER BY salary ASC;
    
    如果需要按照工资降序排序,可以使用:
    SELECT name, salary FROM employees ORDER BY salary DESC;
    
  • 性能分析:单字段排序的性能主要取决于表的大小和排序字段的索引情况。如果排序字段上有索引,查询效率会显著提高。例如,在一个包含 100 万条记录的 employees 表中,如果 salary 字段上有索引,使用 ORDER BY 进行排序,查询时间通常在秒级别。如果没有索引,排序操作可能会相对较慢,尤其是对于大数据量的表。
  • 应用场景:单字段排序适用于需要按照某个字段的顺序展示数据的场景,如按照时间顺序展示订单、按照成绩高低展示学生排名等。例如,按照注册时间降序展示用户:
    SELECT user_id, registration_date FROM users ORDER BY registration_date DESC;
    

5.2 多字段排序

多字段排序允许按照多个字段的顺序对查询结果进行排序,这在实际应用中非常灵活,可以满足更复杂的排序需求。

  • 基本语法SELECT column_name(s) FROM table_name ORDER BY column_name1 [ASC|DESC], column_name2 [ASC|DESC];
  • 示例:假设有一个 employees 表,包含员工的部门、姓名和工资信息,如果需要先按照部门升序排序,再按照工资降序排序,可以使用以下语句:
    SELECT department, name, salary FROM employees ORDER BY department ASC, salary DESC;
    
  • 性能分析:多字段排序的性能同样取决于表的大小和排序字段的索引情况。如果多个排序字段都有索引,查询效率会更高。例如,在一个包含 100 万条记录的 employees 表中,如果 departmentsalary 字段都有索引,使用多字段排序,查询时间通常在秒级别。如果没有索引,排序操作可能会相对较慢,尤其是对于大数据量的表。
  • 应用场景:多字段排序适用于需要同时按照多个字段的顺序展示数据的场景,如先按照地区排序,再按照销售额排序;或者先按照日期排序,再按照优先级排序。例如,先按照产品类别排序,再按照销售额降序展示销售记录:
    SELECT category, product_id, amount FROM sales ORDER BY category ASC, amount DESC;
    

5.3 排序与分页

在实际应用中,尤其是对于大数据量的表,我们通常需要对排序后的结果进行分页展示,以便用户可以逐页查看数据。SQL 提供了 LIMIT(在 MySQL 中)或 ROWNUM(在 Oracle 中)等机制来实现分页查询。

  • 基本语法
    • 在 MySQL 中:SELECT column_name(s) FROM table_name ORDER BY column_name LIMIT offset, rows;
    • 在 Oracle 中:SELECT column_name(s) FROM (SELECT column_name(s), ROWNUM AS rnum FROM table_name WHERE ROWNUM <= end_row) WHERE rnum >= start_row;
  • 示例:假设有一个 employees 表,包含员工的姓名和工资信息,如果需要按照工资降序排序,并分页展示,每页显示 10 条记录,查询第 2 页的数据,可以使用以下语句(以 MySQL 为例):
    SELECT name, salary FROM employees ORDER BY salary DESC LIMIT 10, 10;
    
    这条语句会跳过前 10 条记录,返回第 11 到第 20 条记录。
  • 性能分析:排序与分页的性能主要取决于表的大小、排序字段的索引情况以及分页参数。如果排序字段上有索引,查询效率会显著提高。例如,在一个包含 100 万条记录的 employees 表中,如果 salary 字段上有索引,使用排序与分页查询,查询时间通常在秒级别。如果没有索引,排序和分页操作可能会相对较慢,尤其是对于大数据量的表。
  • 应用场景:排序与分页适用于需要对大量数据进行逐页展示的场景,如分页展示商品列表、分页展示用户评论等。例如,分页展示订单记录,每页显示 20 条记录:
    SELECT order_id, order_date, amount FROM orders ORDER BY order_date DESC LIMIT 20, 20;
    

6. 连接查询语句

6.1 内连接查询

内连接查询用于从两个或多个表中返回匹配的记录,只有当连接的表中存在满足条件的记录时,才会出现在结果集中。这是连接查询中最常用的一种方式,能够有效地整合多个表中的相关数据。

  • 基本语法SELECT column_name(s) FROM table1 INNER JOIN table2 ON table1.column = table2.column;
  • 示例:假设有一个 employees 表和一个 departments 表,employees 表包含员工的基本信息,departments 表包含部门的信息。如果需要查询每个员工所属的部门名称,可以使用以下语句:
    SELECT employees.name, departments.department_name
    FROM employees
    INNER JOIN departments
    ON employees.department_id = departments.department_id;
    
    这条语句会返回所有员工及其对应的部门名称,只有那些在 employees 表和 departments 表中 department_id 匹配的记录才会出现在结果中。
  • 性能分析:内连接查询的性能主要取决于连接条件的复杂度和表的大小。如果连接字段上有索引,查询效率会显著提高。例如,在一个包含 100 万条记录的 employees 表和一个包含 10 万条记录的 departments 表中,如果 department_id 字段上有索引,内连接查询的时间通常在秒级别。如果没有索引,查询可能会相对较慢,尤其是对于大数据量的表。
  • 应用场景:内连接查询适用于需要从多个表中提取相关数据的场景,如查询学生的成绩和对应的课程名称、查询订单和对应的客户信息等。例如,查询每个订单的客户名称和订单金额:
    SELECT customers.customer_name, orders.order_amount
    FROM customers
    INNER JOIN orders
    ON customers.customer_id = orders.customer_id;
    

6.2 左外连接查询

左外连接查询用于从左表中返回所有记录,即使右表中没有匹配的记录,也会出现在结果集中。如果右表中没有匹配的记录,结果集中右表的字段将显示为 NULL。这种查询方式在需要保留左表所有数据的情况下非常有用。

  • 基本语法SELECT column_name(s) FROM table1 LEFT JOIN table2 ON table1.column = table2.column;
  • 示例:假设有一个 employees 表和一个 departments 表,如果需要查询每个员工及其所属的部门名称,即使某些员工没有分配部门,也可以使用以下语句:
    SELECT employees.name, departments.department_name
    FROM employees
    LEFT JOIN departments
    ON employees.department_id = departments.department_id;
    
    这条语句会返回所有员工的记录,即使某些员工的 department_iddepartments 表中没有匹配的记录,这些员工的部门名称将显示为 NULL
  • 性能分析:左外连接查询的性能同样取决于连接条件的复杂度和表的大小。如果连接字段上有索引,查询效率会更高。例如,在一个包含 100 万条记录的 employees 表和一个包含 10 万条记录的 departments 表中,如果 department_id 字段上有索引,左外连接查询的时间通常在秒级别。如果没有索引,查询可能会相对较慢,尤其是对于大数据量的表。
  • 应用场景:左外连接查询适用于需要保留左表所有数据的场景,如查询所有学生及其对应的课程成绩(即使某些学生没有成绩)、查询所有客户及其对应的订单信息(即使某些客户没有订单)等。例如,查询所有客户及其订单金额:
    SELECT customers.customer_name, orders.order_amount
    FROM customers
    LEFT JOIN orders
    ON customers.customer_id = orders.customer_id;
    

6.3 右外连接查询

右外连接查询与左外连接查询相反,它从右表中返回所有记录,即使左表中没有匹配的记录,也会出现在结果集中。如果左表中没有匹配的记录,结果集中左表的字段将显示为 NULL。这种查询方式在需要保留右表所有数据的情况下非常有用。

  • 基本语法SELECT column_name(s) FROM table1 RIGHT JOIN table2 ON table1.column = table2.column;
  • 示例:假设有一个 employees 表和一个 departments 表,如果需要查询每个部门及其所属的员工名称,即使某些部门没有员工,也可以使用以下语句:
    SELECT employees.name, departments.department_name
    FROM employees
    RIGHT JOIN departments
    ON employees.department_id = departments.department_id;
    
    这条语句会返回所有部门的记录,即使某些部门的 department_idemployees 表中没有匹配的记录,这些部门的员工名称将显示为 NULL
  • 性能分析:右外连接查询的性能同样取决于连接条件的复杂度和表的大小。如果连接字段上有索引,查询效率会更高。例如,在一个包含 100 万条记录的 employees 表和一个包含 10 万条记录的 departments 表中,如果 department_id 字段上有索引,右外连接查询的时间通常在秒级别。如果没有索引,查询可能会相对较慢,尤其是对于大数据量的表。
  • 应用场景:右外连接查询适用于需要保留右表所有数据的场景,如查询所有课程及其对应的学生信息(即使某些课程没有学生)、查询所有产品及其对应的订单信息(即使某些产品没有订单)等。例如,查询所有产品及其订单数量:
    SELECT products.product_name, COUNT(orders.order_id) AS order_count
    FROM products
    RIGHT JOIN orders
    ON products.product_id = orders.product_id
    GROUP BY products.product_id;
    

7. 子查询语句

子查询是 SQL 查询中一种非常强大的工具,它允许在一个查询语句中嵌套另一个查询语句。子查询可以用于多种场景,包括作为条件筛选数据、作为数据源提供数据,以及实现复杂的关联查询。以下将从子查询作为条件、子查询作为数据源和相关子查询三个子课题展开论述。

7.1 子查询作为条件

子查询作为条件时,通常用于 WHERE 子句或 HAVING 子句中,通过返回一个值或一组值来筛选数据。这种方式可以实现复杂的条件筛选,尤其是当需要基于另一个查询的结果来筛选数据时。

  • 基本语法
    • 单值子查询:SELECT column_name(s) FROM table_name WHERE column_name operator (SELECT column_name FROM table_name WHERE condition);
    • 多值子查询:SELECT column_name(s) FROM table_name WHERE column_name IN (SELECT column_name FROM table_name WHERE condition);
  • 示例
    • 查询工资高于平均工资的员工信息:
      SELECT * FROM employees WHERE salary > (SELECT AVG(salary) FROM employees);
      
    • 查询与最高工资员工同部门的员工信息:
      SELECT * FROM employees WHERE department_id = (SELECT department_id FROM employees WHERE salary = (SELECT MAX(salary) FROM employees));
      
  • 性能分析:子查询作为条件的性能主要取决于子查询的复杂度和表的大小。如果子查询返回的结果集较小,且主查询的条件字段上有索引,查询效率会较高。例如,在一个包含 100 万条记录的 employees 表中,使用单值子查询查询工资高于平均工资的员工,查询时间通常在秒级别。
  • 应用场景:子查询作为条件适用于需要基于另一个查询结果进行筛选的场景,如查询特定条件下的数据、查询与某个特定记录相关的数据等。例如,查询与某个特定客户有相同订单的其他客户:
    SELECT * FROM customers WHERE customer_id IN (SELECT customer_id FROM orders WHERE order_id = (SELECT order_id FROM orders WHERE customer_id = 1001));
    

7.2 子查询作为数据源

子查询作为数据源时,通常用于 FROM 子句中,将子查询的结果作为一个临时表或派生表,供主查询使用。这种方式可以实现复杂的多表查询,尤其是当需要对多个表进行联合查询时。

  • 基本语法SELECT column_name(s) FROM (SELECT column_name(s) FROM table_name WHERE condition) AS derived_table;
  • 示例
    • 查询每个部门工资最高的员工信息:
      SELECT department_id, name, salary
      FROM (
          SELECT department_id, name, salary,
                 ROW_NUMBER() OVER (PARTITION BY department_id ORDER BY salary DESC) AS rank
          FROM employees
      ) AS ranked_employees
      WHERE rank = 1;
      
    • 查询每个部门的平均工资和员工数量:
      SELECT department_id, AVG(salary) AS avg_salary, COUNT(*) AS employee_count
      FROM employees
      GROUP BY department_id;
      
  • 性能分析:子查询作为数据源的性能主要取决于子查询的复杂度和主查询的复杂度。如果子查询返回的结果集较小,且主查询的条件字段上有索引,查询效率会较高。例如,在一个包含 100 万条记录的 employees 表中,使用子查询查询每个部门工资最高的员工,查询时间通常在秒级别。
  • 应用场景:子查询作为数据源适用于需要对多个表进行联合查询的场景,如查询每个部门的统计数据、查询每个产品的销售数据等。例如,查询每个产品的总销售额和订单数量:
    SELECT product_id, SUM(amount) AS total_sales, COUNT(*) AS order_count
    FROM orders
    GROUP BY product_id;
    

7.3 相关子查询

相关子查询是指子查询的执行依赖于主查询的结果,即子查询中包含主查询的列或表。这种方式可以实现复杂的关联查询,尤其是当需要基于主查询的每一行结果来动态生成子查询时。

  • 基本语法SELECT column_name(s) FROM table_name WHERE column_name operator (SELECT column_name FROM table_name WHERE condition);
  • 示例
    • 查询每个员工的工资与部门平均工资的比较:
      SELECT e.name, e.salary, d.avg_salary
      FROM employees e
      JOIN (
          SELECT department_id, AVG(salary) AS avg_salary
          FROM employees
          GROUP BY department_id
      ) AS d ON e.department_id = d.department_id;
      
    • 查询每个员工的工资是否高于部门平均工资:
      SELECT e.name, e.salary, d.avg_salary,
             CASE WHEN e.salary > d.avg_salary THEN '高于平均工资' ELSE '低于或等于平均工资' END AS salary_comparison
      FROM employees e
      JOIN (
          SELECT department_id, AVG(salary) AS avg_salary
          FROM employees
          GROUP BY department_id
      ) AS d ON e.department_id = d.department_id;
      
  • 性能分析:相关子查询的性能通常比普通子查询要低,因为子查询需要为每一行主查询的结果动态执行。如果主查询的表较大,且子查询的条件字段上有索引,查询效率会有所提升。例如,在一个包含 100 万条记录的 employees 表中,使用相关子查询查询每个员工的工资与部门平均工资的比较,查询时间通常在秒级别。
  • 应用场景:相关子查询适用于需要基于主查询的每一行结果动态生成子查询的场景,如查询每个员工的绩效与部门平均绩效的比较、查询每个产品的销售额与类别平均销售额的比较等。例如,查询每个产品的销售额是否高于类别平均销售额:
    SELECT o.product_id, o.amount, c.avg_amount,
           CASE WHEN o.amount > c.avg_amount THEN '高于平均销售额' ELSE '低于或等于平均销售额' END AS amount_comparison
    FROM orders o
    JOIN (
        SELECT product_id, AVG(amount) AS avg_amount
        FROM orders
        GROUP BY product_id
    ) AS c ON o.product_id = c.product_id;
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/981354.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2025年AI PPT工具精选:让演示文稿更智能、更高效

&#x1f4a1; 做PPT太难&#xff1f;没灵感&#xff1f;排版不好看&#xff1f;别怕&#xff0c;AI已经帮你安排好了&#xff01; 想知道2025年最值得推荐的AI PPT工具是哪款&#xff1f;答案就是——秒出PPT&#xff01;&#x1f680; 不仅能一键生成PPT&#xff0c;还能自…

qt-C++笔记之ubuntu22.04源码安装Qt6.8.2

qt-C笔记之ubuntu22.04源码安装Qt6.8.2 code review! 文章目录 qt-C笔记之ubuntu22.04源码安装Qt6.8.21.作者环境&#xff1a;ubuntu22.04、cmake202.安装3.关联已安装的 Qt6 到 Qt Creator4.附&#xff1a;ubuntu18.0的处理&#xff0c;可尝试&#xff0c;作者没有遇到这个问题…

单例模式(线程案例)

单例模式可以分为两种&#xff1a;1.饿汉模式 2.懒汉模式 一.饿汉模式 //饿汉模式&#x1f447; class MySingleTon{//因为这是一个静态成员变量&#xff0c;在类加载的时候&#xff0c;就创建了private static MySingleTon mySingleTon new MySingleTon();//创建一个静…

基于Matlab的多目标粒子群优化

在复杂系统的设计、决策与优化问题中&#xff0c;常常需要同时兼顾多个相互冲突的目标&#xff0c;多目标粒子群优化&#xff08;MOPSO&#xff09;算法应运而生&#xff0c;作为群体智能优化算法家族中的重要成员&#xff0c;它为解决此类棘手难题提供了高效且富有创新性的解决…

(2025年)工会考试该如何高效备考?有学习方法吗?

工会考试备考文章 工会考试高效备考指南 工会在维护职工权益、促进企业和谐发展中扮演着重要角色&#xff0c;工会考试则是选拔优秀工会工作者的关键途径。面对工会考试涉及的法律法规、组织管理以及维权服务等多方面知识&#xff0c;掌握科学备考方法是成功的关键。 法律法规是…

《机器学习数学基础》补充资料:向量范数

《机器学习数学基础》第1章1.5.3节介绍了向量范数的基本定义。 本文在上述基础上&#xff0c;介绍向量范数的有关性质。 注意&#xff1a; 以下均在欧几里得空间讨论&#xff0c;即欧氏范数。 1. 性质 实&#xff08;或复&#xff09;向量 x \pmb{x} x &#xff0c;范数 ∥…

Unity NGUI新手向几个问题记录

1.点Button没反应 制作Button组件时&#xff0c;不光要挂载Button脚本&#xff0c;还有挂载BoxCollider BoxCollider 接收事件 2.Button点击事件的增加与删除 使用.onClick.add增加事件&#xff0c;使用.onClick.Remove,.onClick.RemoveAt,onClick.RemoveRang,onClick.Clear移…

servlet tomcat

在spring-mvc demo程序运行到DispatcherServlet的mvc处理 一文中&#xff0c;我们实践了浏览器输入一个请求&#xff0c;然后到SpringMvc的DispatcherServlet处理的整个流程. 设计上这些都是tomcat servlet的处理 那么究竟这是怎么到DispatcherServlet处理的&#xff0c;本文将…

UniApp 中封装 HTTP 请求与 Token 管理(附Demo)

目录 1. 基本知识2. Demo3. 拓展 1. 基本知识 从实战代码中学习&#xff0c;上述实战代码来源&#xff1a;芋道源码/yudao-mall-uniapp 该代码中&#xff0c;通过自定义 request 函数对 HTTP 请求进行了统一管理&#xff0c;并且结合了 Token 认证机制 请求封装原理&#xff…

【音视频】ffmpeg命令分类查询

一、ffmpeg命令分类查询 -version&#xff1a;显示版本 ffmpeg -version-buildconf&#xff1a;显示编译配置&#xff0c;这里指的是你编译好的ffmpeg的选项 ffmpeg -buildconf-formats:显示可用格式&#xff08;muxersdemuxers&#xff09;&#xff0c;复用器和解复用器&am…

基于Windows11的DockerDesktop安装和布署方法简介

基于Windows11的DockerDesktop安装和布署方法简介 一、下载安装Docker docker 下载地址 https://www.docker.com/ Download Docker Desktop 选择Download for Winodws AMD64下载Docker Desktop Installer.exe 双点击 Docker Desktop Installer.exe 进行安装 测试Docker安装是…

C++发展

目录 ​编辑C 的发展总结&#xff1a;​编辑 1. C 的早期发展&#xff08;1979-1985&#xff09; 2. C 标准化过程&#xff08;1985-1998&#xff09; 3. C 标准演化&#xff08;2003-2011&#xff09; 4. C11&#xff08;2011年&#xff09; 5. C14&#xff08;2014年&a…

爬虫Incapsula reese84加密案例:Etihad航空

声明: 该文章为学习使用,严禁用于商业用途和非法用途,违者后果自负,由此产生的一切后果均与作者无关 一、找出需要加密的参数 1.js运行 atob(‘aHR0cHM6Ly93d3cuZXRpaGFkLmNvbS96aC1jbi8=’) 拿到网址,F12打开调试工具,随便搜索航班,切换到network搜索一个时间点可以找…

【分享】网间数据摆渡系统,如何打破传输瓶颈,实现安全流转?

在数字化浪潮中&#xff0c;企业对数据安全愈发重视&#xff0c;网络隔离成为保护核心数据的重要手段。内外网隔离、办公网与研发网隔离等措施&#xff0c;虽为数据筑牢了防线&#xff0c;却也给数据传输带来了诸多难题。传统的数据传输方式在安全性、效率、管理等方面暴露出明…

uploadlabs经验总结

目录 一、基础上传漏洞&#xff08;太过简单目前环境不可能存在&#xff09; 1、抓包然后改后缀进行绕过 2、抓包然后改上传文件类型进行绕过 3、改后缀大小写绕过&#xff0c;以及收尾加空格&#xff0c;加::$DATA,加点等等 4、黑名单不完整绕过&#xff0c;复习后缀绕过&…

数据结构:二叉树的链式结构及相关算法详解

目录 一.链式结构的实现 1.二叉树结点基本结构&#xff0c;初始化与销毁&#xff1a; 二.链式结构二叉树的几种遍历算法 1.几种算法的简单区分&#xff1a; 2.前序遍历&#xff1a; 3.中序遍历&#xff1a; 4.后序遍历&#xff1a; 5.层序遍历&#xff08;广度优先遍历B…

VSCode 移除EmmyLua插件的红色波浪线提示

VSCode 中安装插件EmmyLua&#xff0c;然后打开lua文件的时候&#xff0c;如果lua代码引用了C#脚本的变量&#xff0c;经常出现 “undefined global variable: UnityEngineEmmyLua(undefined-global)” 的红色波浪线提示&#xff0c;这个提示看着比较烦人&#xff0c;我们可以通…

MWC 2025 | 紫光展锐联合移远通信推出全面支持R16特性的5G模组RG620UA-EU

2025年世界移动通信大会&#xff08;MWC 2025&#xff09;期间&#xff0c;紫光展锐联合移远通信&#xff0c;正式发布了全面支持5G R16特性的模组RG620UA-EU&#xff0c;以强大的灵活性和便捷性赋能产业。 展锐芯加持&#xff0c;关键性能优异 RG620UA-EU模组基于紫光展锐V62…

springboot425-基于SpringBoot的BUG管理系统(源码+数据库+纯前后端分离+部署讲解等)

&#x1f495;&#x1f495;作者&#xff1a; 爱笑学姐 &#x1f495;&#x1f495;个人简介&#xff1a;十年Java&#xff0c;Python美女程序员一枚&#xff0c;精通计算机专业前后端各类框架。 &#x1f495;&#x1f495;各类成品Java毕设 。javaweb&#xff0c;ssm&#xf…

机器人“照镜子”:开启智能新时代

机器人也爱 “照镜子”&#xff1f; 在科技飞速发展的今天&#xff0c;机器人的身影越来越频繁地出现在我们的生活和工作中。它们承担着各种各样的任务&#xff0c;从工业生产线上的精密操作&#xff0c;到家庭中的清洁服务&#xff0c;再到危险环境下的救援工作。然而&#xf…