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;
此外,还可以使用多种条件运算符,如=
、<
、>
、<=
、>=
、<>
(不等于)等,以及逻辑运算符AND
、OR
、NOT
来组合复杂的条件。例如,查询工资大于5000且职位为“经理”的员工信息:
SELECT * FROM employees WHERE salary > 5000 AND position = '经理';
这种条件查询方式在实际应用中非常灵活,可以根据具体需求精确地筛选数据。
2. 条件查询语句
2.1 单条件查询
单条件查询是 SQL 查询中最为基础且常见的类型,它通过一个简单的条件筛选数据,能够快速定位到符合特定要求的记录。在实际应用中,单条件查询的使用频率非常高,尤其是在数据筛选和初步分析阶段。
- 基本语法:
SELECT column_name(s) FROM table_name WHERE condition;
- 示例:假设有一个
employees
表,包含员工的姓名、职位、工资等信息,如果需要查询工资大于 5000 的员工信息,可以使用以下语句:
这条语句会返回所有工资大于 5000 的员工记录,包括他们的姓名、职位、工资等所有字段。SELECT * FROM employees WHERE salary > 5000;
- 性能分析:单条件查询的性能主要取决于条件的复杂度以及表的索引情况。如果表中存在针对查询条件的索引(如在
salary
字段上有索引),查询效率会显著提高。例如,在一个包含 100 万条记录的employees
表中,如果没有索引,查询可能需要扫描整个表,耗时较长;而如果在salary
字段上有索引,查询时间可以缩短到毫秒级别。 - 应用场景:单条件查询适用于简单的数据筛选场景,如查询某个特定时间段内的数据、某个特定状态的数据等。例如,查询最近一个月内注册的用户:
SELECT * FROM users WHERE registration_date >= DATE_SUB(CURDATE(), INTERVAL 1 MONTH);
2.2 多条件查询
多条件查询允许通过多个条件组合来筛选数据,能够更精确地定位到符合多个要求的记录。通过逻辑运算符 AND
、OR
和 NOT
,可以实现复杂的条件组合,满足多样化的数据查询需求。
- 基本语法:
- 使用
AND
:SELECT column_name(s) FROM table_name WHERE condition1 AND condition2;
- 使用
OR
:SELECT column_name(s) FROM table_name WHERE condition1 OR condition2;
- 使用
NOT
:SELECT 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;
- 查询工资大于 5000 且职位为“经理”的员工信息:
- 性能分析:多条件查询的性能同样取决于条件的复杂度和索引情况。如果多个条件都涉及索引字段,查询效率会更高。例如,在一个包含 100 万条记录的
employees
表中,如果salary
和position
字段都有索引,使用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_date
和product_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 的部门,可以使用以下语句:
这条语句会将员工按照部门分组,计算每个部门的平均工资,并筛选出平均工资大于 5000 的部门。SELECT department, AVG(salary) AS avg_salary FROM employees GROUP BY department HAVING AVG(salary) > 5000;
- 性能分析:分组后筛选的性能主要取决于分组查询的效率和筛选条件的复杂度。如果分组字段上有索引,查询效率会更高。例如,在一个包含 100 万条记录的
employees
表中,如果department
字段上有索引,使用GROUP BY
和HAVING
子句进行筛选,查询时间通常在秒级别。 - 应用场景:分组后筛选适用于需要对分组结果进行进一步筛选的场景,如筛选销售额超过某个阈值的产品、筛选员工数量超过某个阈值的部门等。例如,筛选销售额超过 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
表中,如果department
和salary
字段都有索引,使用多字段排序,查询时间通常在秒级别。如果没有索引,排序操作可能会相对较慢,尤其是对于大数据量的表。 - 应用场景:多字段排序适用于需要同时按照多个字段的顺序展示数据的场景,如先按照地区排序,再按照销售额排序;或者先按照日期排序,再按照优先级排序。例如,先按照产品类别排序,再按照销售额降序展示销售记录:
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;
- 在 MySQL 中:
- 示例:假设有一个
employees
表,包含员工的姓名和工资信息,如果需要按照工资降序排序,并分页展示,每页显示 10 条记录,查询第 2 页的数据,可以使用以下语句(以 MySQL 为例):
这条语句会跳过前 10 条记录,返回第 11 到第 20 条记录。SELECT name, salary FROM employees ORDER BY salary DESC LIMIT 10, 10;
- 性能分析:排序与分页的性能主要取决于表的大小、排序字段的索引情况以及分页参数。如果排序字段上有索引,查询效率会显著提高。例如,在一个包含 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_id
在departments
表中没有匹配的记录,这些员工的部门名称将显示为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_id
在employees
表中没有匹配的记录,这些部门的员工名称将显示为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 rankFROM 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_salaryFROM employeesGROUP 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_salaryFROM employeesGROUP 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_amountFROM ordersGROUP BY product_id ) AS c ON o.product_id = c.product_id;
相关文章:
SQL经典常用查询语句
1. 基础查询语句 1.1 查询表中所有数据 在SQL中,查询表中所有数据是最基本的操作之一。通过使用SELECT * FROM table_name;语句,可以获取指定表中的所有记录和列。例如,假设有一个名为employees的表,包含员工的基本信息…...
0005__PyTorch 教程
PyTorch 教程 | 菜鸟教程 离线包:torch-1.13.1cpu-cp39-cp39-win_amd64.whl https://download.pytorch.org/whl/torch_stable.html...
高并发场景下的数据库优化
在高并发系统中,数据库通常是性能瓶颈。面对高并发请求,我们需要采用合适的优化策略,以保证数据库的稳定性和高效性。本文将介绍数据库高并发问题的成因,并结合 Mybatis-Plus,探讨 乐观锁、悲观锁、高并发优化及数据库…...
Linux:同步
目录 一、同步概念 条件变量 二、生产者消费者模型 三、环形队列 一、同步概念 互斥用来解决 访问临界资源 的非原子性,通俗来说,由于互斥锁的实现,保证了在用户角度看,同一个时间内访问临界资源的代码只有一个线程在执行。 而…...
GB28181开发--ZLMediaKit+WVP+Jessibuca
一、核心组件功能 1、ZLMediaKit 定位:基于 C++11 的高性能流媒体服务框架,支持 RTSP/RTMP/HLS/HTTP-FLV 等协议互转,具备低延迟(最低 100ms)、高并发(单机 10W 级连接)特性,适用于商用级流媒体服务器部署。 特性:跨平台(Linux/Windows/ARM 等)、支持 …...
23种设计模式之《备忘录模式(Memento)》在c#中的应用及理解
程序设计中的主要设计模式通常分为三大类,共23种: 1. 创建型模式(Creational Patterns) 单例模式(Singleton):确保一个类只有一个实例,并提供全局访问点。 工厂方法模式࿰…...
Oracle删除重复数据保留其中一条
Oracle删除重复数据保留其中一条 在Oracle数据库中,要删除重复数据并保留其中一条记录,可以使用多种方法。这里介绍两种常见的方法:使用ROWID或使用ROW_NUMBER()窗口函数。 方法1:使用ROWID ROWID是Oracle中用来唯一标识表中每…...
deepseek助力运维和监控自动化
将DeepSeek与Agent、工作流及Agent编排技术结合,可实现IT运维与监控的智能化闭环管理。以下是具体应用框架和场景示例: 一、智能Agent体系设计 多模态感知Agent 日志解析Agent:基于DeepSeek的NLP能力,实时解析系统日志中的语义&a…...
16.1STM32_ADC
STM32_ADC 数字信号分为高/低电平两种状态 模拟信号就是任意的电压值 STM32芯片内就是一整套的数字逻辑电路,来实现我们的程序执行,以及各种各样的外设功能, ADC(模拟-数字转换技术)的功能就是将模拟信号转化为数字…...
神经网络 - 激活函数(Swish函数、GELU函数)
一、Swish 函数 Swish 函数是一种较新的激活函数,由 Ramachandran 等人在 2017 年提出,其数学表达式通常为 其中 σ(x) 是 Sigmoid 函数(Logistic 函数)。 如何理解 Swish 函数 自门控特性 Swish 函数可以看作是对输入 x 进行“…...
VS2015 c++和cmake配置编程
Visual Studio 2015:确保安装了C开发工具,并安装“使用C的桌面开发”工作负载。CMake:可以从 CMake官网 下载并安装,并将其添加到系统环境变量中。vs加载项目启动Visual Studio。选择“继续但无代码”。点击“文件”。选择 “打开…...
如何为 Web 前端开发面试做好准备
大家好!我是 [数擎AI],一位热爱探索新技术的前端开发者,在这里分享前端和Web3D、AI技术的干货与实战经验。如果你对技术有热情,欢迎关注我的文章,我们一起成长、进步! 开发领域:前端开发 | AI 应…...
深入探索像ChatGPT这样的大语言模型
参考 【必看珍藏】2月6日,安德烈卡帕西最新AI普及课:深入探索像ChatGPT这样的大语言模型|Andrej Karpathy fineweb知乎翻译介绍 fineweb-v1原始连接 fineweb中文翻译版本 Chinese Fineweb Edu数据集 查看网络的内部结果,可以参…...
代码贴——堆(二叉树)数据结构
头文件Heap.h #pragma once #include<bits/stdc.h> typedef int HPDataType;typedef struct Heap {HPDataType* a;int size;int capacity; }HP;void HPInit(HP* php); void HPDestory(HP* php); //出入后保持数据是堆 void HPPush(HP* php,HPDataType x); HPDataType HP…...
office或者word排版中,复制/黏贴进来文字不会自动换行,如何处理?
李升伟 整理 一、思考与分析 在Office或Word中复制粘贴文字时,文字不会自动换行,需要处理这个问题。首先,我得回想一下常见的原因和解决方法。可能的情况有很多,比如文本带有硬回车、段落格式设置问题,或者文本框的自…...
最新!!!DeepSeek开源周发布内容汇总
本周,人工智能领域的新锐力量DeepSeek宣布将于本周举办“开源周”(Open Source Week),连续五天每日开源一个核心代码库,以透明的方式与全球开发者分享其在通用人工智能(AGI)探索中的最新成果。以…...
【MySQL】(2) 库的操作
SQL 关键字,大小写不敏感。 一、查询数据库 show databases; 注意加分号,才算一句结束。 二、创建数据库 {} 表示必选项,[] 表示可选项,| 表示任选其一。 示例:建议加上 if not exists 选项。 三、字符集编码和排序…...
记一次渗透测试实战:SQL注入漏洞的挖掘与利用
0x01 漏洞发现 在对某网站进行安全测试时,发现以下URL存在异常: https://******.com/search.php?keyword1&zt1954&dw1885&zz& 当参数keyword和zt被赋值为-1时页面返回特殊内容,初步判断存在SQL注入漏洞。 0x02 注入验证…...
Gin框架从入门到实战:核心用法与最佳实践
为什么选择Gin框架? Gin 是一个基于 Go 语言的高性能 Web 框架,具备以下优势: 轻量高效:底层依赖 net/http,性能接近原生。简洁优雅:API 设计友好,支持路由分组、中间件链、参数绑定等特性。生…...
PyTorch 的 nn.NLLLoss:负对数似然损失全解析
PyTorch 的 nn.NLLLoss:负对数似然损失全解析 在 PyTorch 的损失函数家族中,nn.NLLLoss(Negative Log Likelihood Loss,负对数似然损失)是一个不太起眼但非常重要的成员。它经常跟 LogSoftmax 搭配出现,尤…...
ROS2软件调用架构和机制解析:Publisher创建
术语 DDS (Data Distribution Service): 用于实时系统的数据分发服务标准,是ROS 2底层通信的基础RMW (ROS Middleware): ROS中间件接口,提供与具体DDS实现无关的抽象APIQoS (Quality of Service): 服务质量策略,控制通信的可靠性、历史记录、…...
vue2 以及vue3中 v-if和v-for是否可以同时使用
vue2以及vue3官方文档中都明确的指出 避免 v-if 和 v-for 用在一起 vue2 官方文档 解释 在 Vue 2 中,v-for 的优先级高于 v-if,也就是说,Vue 2 在渲染时,会先处理 v-for 生成列表项,再对子项判断 v-if 是否渲染。 …...
Hbase伪分布安装教程,详细版
注意Hbase版本与Hadoop版本的兼容,还有与JDK版本的兼容 本次用到的Hbase为2.4.6版本,Hadoop为3.1.3版本,JDK为JDK8 打开下面的网址查看兼容问题 Apache HBase Reference Guidehttps://hbase.apache.org/book.html#configuration 点击基础先…...
SSL: CERTIFICATE_VERIFY_FAILED Error in Python 是什么问题?
在最新版本的Stable Diffusion webui 版本上使用最新下载的模型时,出现了类似的错误。 SSL: CERTIFICATE_VERIFY_FAILED 错误在Python中通常表示你的程序试图通过HTTPS连接到某个服务器,但Python无法验证该服务器提供的SSL证书。这可能是因为以下几种原…...
15Metasploit框架介绍
metasploit目录结构 MSF ——the metasploit framework 的简称。MSF高度模块化,即框架结构由多个module组成,是全球最受欢迎的工具 是一筐开源安全漏洞利用和测试工具,集成了各种平台上常见的溢出漏洞和流行sheellcode,并且保持…...
【Qt】ffmpeg解码—照片提取、视频播放▲
目录 一、图像的成像原理: RGB成像原理: YUV成像原理: 二、多线程 三、ffmpeg解码(照片提取) 1.准备工作 (1)在工程文件夹里面新建三个文件夹 (2)在main函数中加…...
Springboot整合WebSocket+Redis以及微信小程序如何调用
一、 Springboot整合WebSocket 1. 引入socket依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId> </dependency>引入依赖后需要刷新maven,Websocket的版本默认跟随S…...
HOW - 在Windows浏览器中模拟MacOS的滚动条
目录 一、原生 CSS 代码实现模拟 macOS 滚动条额外优化应用到某个特定容器 二、Antd table中的滚动条场景三、使用第三方工具/扩展 如果你想让 Windows 里的滚动条 模拟 macOS 的效果(细窄、圆角、隐藏默认轨道)。 可以使用以下几种方案: 一…...
openEuler环境下GlusterFS分布式存储集群部署指南
1.环境准备: os:openEuler 22.03 主机名 IP地址 主机用途 Rocky8192.168.121.160客户端 open-Euler1192.168.121.150节点1,提供两块6G硬盘open-Euler4192.168.121.153节点2,提供两块6G硬盘open-Euler5192.168.121.154 …...
C++学习(七)(标准库+STL(iotstream公司,日期/时间,器皿,算法,迭代器,多线程))
C 标准模板库 (STL) C 标准模板库 (STL) 是头文件的集合,提供了多种数据结构、算法和函数,以简化您的 C 编码体验。STL 的主要目的是通过提供一套现成的有用工具来节省时间并提高效率。STL 最常用的功能可…...
c高级第五天
1> 在终端提示输入一个成绩,通过shell判断该成绩的等级 [90,100] : A [80, 90) : B [70, 80) : C [60, 70) : D [0, 60) : 不及格 #!/bin/bash# 提示用户输入成绩 read -p "请输入成绩(0-100):" score# 判断成…...
Windows上使用go-ios实现iOS17自动化
前言 在Windows上运行iOS的自动化,tidevice对于iOS17以上并不支持,原因是iOS 17 引入新通信协议 RemoteXPCQUIC,改变了 XCUITest 的启动方式。 一、go-ios的安装 1、安装命令:npm i go-ios 2、安装完成后输入命令which io…...
迷你世界脚本小地图接口:Mapmark
小地图接口:Mapmark 彼得兔 更新时间: 2023-10-25 10:33:48 具体函数名及描述如下: 序号 函数名 函数描述 1 newShape(...) 新增一个形状(线,矩形,圆形) 2 deleteShape(...) 删除一个形状 3 setShapeColor(...) 设置…...
TMS320F28P550SJ9学习笔记1:CCS导入工程以及测试连接单片机仿真器
学习记录如何用 CCS导入工程以及测试连接单片机仿真器 以下为我的CCS 以及驱动库C2000ware 的版本 CCS版本: Code Composer Studio 12.8.1 C2000ware :C2000Ware_5_04_00_00 目录 CCS导入工程: 创建工程: 添加工程: C…...
为什么要提倡尽早返回(Early Return)
为什么要提倡尽早返回(Early Return) 在编程中,“尽早返回”(Early Return)是一种常被提倡的编程方式,特别是在需要提升代码可读性、减少嵌套层级、以及快速处理异常情况时。本文将讨论尽早返回的优点、应…...
Gartner发布安全运营指标构建指南
如何为安全运营指标构建坚实的基础 安全运营经理需要报告威胁检测、调查和响应计划的有效性,但难以驾驭大量潜在的 SOC 指标。本研究提供了设计针对 SOC 的指标系统的示例和实践。 主要发现 需要清晰、一致的衡量标准来向董事会成员或服务提供商等更广泛的团队传达…...
vue3:初学 vue-router 路由配置
承上一篇:nodejs:express js-mdict 作为后端,vue 3 vite 作为前端,在线查询英汉词典 安装 cnpm install vue-router -S 现在讲一讲 vue3:vue-router 路由配置 cd \js\mydict-web\src mkdir router cd router 我还…...
数据结构入门篇——什么是数据结构。
一、引入 工具是一种什么东西呢?是一种转化媒介,我们需要熟食,我们要通过用火来将生肉烤熟。在这个过程中。我们要输入一个东西——生肉,通过工具——火的加工,从而得到我们的目的产物——熟肉。 将上面的例子和红字部…...
uniapp+vue3搭建项目
工具使用: Pinia Vue 3 官方推荐的状态管理库,比 Vuex 更轻量,支持模块化,结合 persistedstate 插件可以持久化存储数据。uView-plus 专为 UniApp 设计,支持 App、小程序、H5。UnoCSS 更轻量,比 TailwindCS…...
unity大坐标抖动处理测试
第二幅图就是相机坐标是0 6360094 0的地方看见的模型,可以看见这个球体已经烂了 那么这里可以知道的是坐标太大了导致的,那么把所有物体共同偏移一下,即可得到第一幅图的效果,圆润的sphere又回来了 浮点数的计算是需要位数的&…...
CASAIM与承光电子达成深度合作,三维扫描逆向建模技术助力车灯设计与制造向数字化与智能化转型
近日,CASAIM与广州承光电子科技有限公司正式达成深度合作,CASAIM将为承光电子提供全方位的技术支持,包括高精度三维扫描设备、逆向建模软件以及定制化的技术解决方案。双方将共同组建技术团队,针对车灯设计中的难点进行攻关&#…...
C++类与对象:银行管理系统项目实战开发LeetCode每日一题
[Bank-Management-System]银行管理系统项目 以下是一个可运行的C银行账户类(支持简单的存款/取款)。后面会继续完善该项目: #include <iostream> #include <string> using namespace std;class Account{public://构造函数Accou…...
领域驱动设计:事件溯源架构简介
概述 事件溯源架构通常由3种应用设计模式组成,分别是:事件驱动(Event Driven),事件溯源(Event Source)、CQRS(读写分离)。这三种应用设计模式常见于领域驱动设计(DDD)中,但它们本身是一种应用设计的思想,不仅仅局限于DDD,每一种模式都可以单独拿出来使用。 E…...
景联文科技:以专业标注赋能AI未来,驱动智能时代的精准跃迁
在人工智能技术重塑全球产业格局的今天,高质量训练数据已成为驱动算法进化的核心燃料。作为数据智能服务领域的领军者,景联文科技深耕数据标注行业多年,以全栈式数据解决方案为核心,构建起覆盖数据采集、清洗、标注、质检及算法调…...
LeetCode 热题 100----1.两数之和
LeetCode 热题 100----1.两数之和 题目描述 我的解法 语言:js 思路就是:用双重循环去找哪两个数字相加等于target,目前的时间复杂度为O(n2),之后右优化思路再更新。...
GIT 常用命令
/ 一、环境: ssh-keygen -t rsa -C "wangxiaoerqq.com.cn" 生成本地秘钥(邮箱换成自己的邮箱) 使用cat ~/.ssh/id_rsa.pub查看秘钥 git config --global user.name "wangxiaoer" git config --global wangxiaoerqq.…...
Netty笔记13:序列化
Netty笔记1:线程模型 Netty笔记2:零拷贝 Netty笔记3:NIO编程 Netty笔记4:Epoll Netty笔记5:Netty开发实例 Netty笔记6:Netty组件 Netty笔记7:ChannelPromise通知处理 Netty笔记8…...
IntelliJ IDEA 构建项目时内存溢出问题
问题现象 在使用 IntelliJ IDEA 构建 Java 项目时,遇到了以下错误: java: java.lang.OutOfMemoryError: Java heap space java.lang.RuntimeException: java.lang.OutOfMemoryError: Java heap space这是一个典型的 Java 堆内存不足错误,表…...
Asp.Net Core WebAPI开发教程(入门)
一、Asp.Net Core WebAPI项目创建 二、Asp.Net Core WebApi/Mvc路由定义 二、Asp.Net Core WebAPI 请求案例 Asp.Net WebApi Get请求整理(一) Asp.Net WebApi Post请求整理(一) Asp.Net WebApi Action命名中已‘Get’开头问题 …...
golang 内存对齐和填充规则
内存对齐和填充规则 对齐要求:每个数据类型的起始地址必须是其大小的倍数。 int8(1字节):不需要对齐。int16(2字节):起始地址必须是2的倍数。int32(4字节):起…...