当前位置: 首页 > article >正文

高级sql技巧进阶教程

SQL(Structured Query Language)是用来管理和操作关系型数据库的标准语言。在数据库开发和优化中,高级SQL技巧能够帮助你编写更高效、更灵活的查询,同时提升性能。以下是一些常见的高级SQL技巧,它们可以帮助你在复杂查询、数据优化和数据库管理中更加得心应手。

1. 窗口函数(Window Functions)

窗口函数是SQL中强大的功能,它允许你在结果集的特定“窗口”内执行计算,而不需要使用GROUP BY。窗口函数通常用于排序、排名、累计求和等场景。

示例:排名
 

sql

复制代码

SELECT employee_id, department_id, salary, RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) AS salary_rank FROM employees;

说明RANK() 函数为每个部门的员工按薪水降序排列并计算排名,PARTITION BY 是用来分区的,相同的 department_id 会在一个分区内计算。

2. 自连接(Self Join)

自连接是指一个表与自身进行连接。通常用于查询一个表中与同一表中其他记录之间的关系。

示例:找出员工与其经理
 

sql

复制代码

SELECT e.employee_id AS employee, e.name AS employee_name, m.employee_id AS manager, m.name AS manager_name FROM employees e LEFT JOIN employees m ON e.manager_id = m.employee_id;

说明:这里 employees 表通过自连接来显示员工和经理之间的关系。

3. CTE(公共表表达式)和递归查询

公共表表达式(CTE)让查询更加模块化,可以在查询中使用临时的结果集。递归查询允许你执行层级结构的数据查询,例如树形结构数据。

示例:计算员工的管理层级
 

sql

复制代码

WITH RECURSIVE EmployeeHierarchy AS ( SELECT employee_id, manager_id, 1 AS level FROM employees WHERE manager_id IS NULL -- 找到顶级经理 UNION ALL SELECT e.employee_id, e.manager_id, eh.level + 1 FROM employees e INNER JOIN EmployeeHierarchy eh ON e.manager_id = eh.employee_id ) SELECT * FROM EmployeeHierarchy;

说明:这个查询通过递归CET展示员工及其层级关系。

4. CASE语句和条件聚合(Conditional Aggregation)

CASE 语句在SQL中用于执行条件判断,可以在 SELECTUPDATEDELETE 等语句中使用。结合聚合函数,它可以帮助你实现条件聚合。

示例:按部门统计薪水
 

sql

复制代码

SELECT department_id, SUM(CASE WHEN gender = 'M' THEN salary ELSE 0 END) AS male_salary, SUM(CASE WHEN gender = 'F' THEN salary ELSE 0 END) AS female_salary FROM employees GROUP BY department_id;

说明:使用 CASE 语句进行条件聚合,分别统计男性和女性员工的薪资总和。

5. 子查询(Subqueries)和相关子查询(Correlated Subqueries)

子查询是嵌套在其他查询中的查询,通常用于筛选或计算。相关子查询是指在子查询中引用外部查询的字段。

示例:使用子查询获取最高薪水的员工
 

sql

复制代码

SELECT employee_id, name, salary FROM employees WHERE salary = (SELECT MAX(salary) FROM employees);

说明:这个查询返回薪水最高的员工。子查询先计算出最大薪水,然后外部查询返回薪水等于该值的员工。

示例:相关子查询(查询每个员工的经理是否在同一个部门)
 

sql

复制代码

SELECT e.employee_id, e.name FROM employees e WHERE EXISTS ( SELECT 1 FROM employees m WHERE m.employee_id = e.manager_id AND m.department_id = e.department_id );

说明:相关子查询使用 EXISTS 检查每个员工的经理是否在同一部门。

6. 索引优化(Index Optimization)

通过创建索引,可以加速查询,尤其是对于大数据量的表。掌握索引的使用是提升查询效率的关键。

示例:创建单列索引
 

sql

复制代码

CREATE INDEX idx_employee_name ON employees(name);

说明:在 employees 表的 name 列上创建一个索引,能加速通过 name 查询数据的速度。

示例:创建联合索引
 

sql

复制代码

CREATE INDEX idx_employee_dept_salary ON employees(department_id, salary);

说明:创建一个联合索引,这个索引能加速同时基于 department_idsalary 的查询。

7. 联合查询(UNION 和 UNION ALL)

UNIONUNION ALL 用于将多个 SELECT 语句的结果合并。UNION 会去重,UNION ALL 会保留重复数据。

示例:合并两个不同地区的员工数据
 

sql

复制代码

SELECT employee_id, name FROM employees WHERE region = 'East' UNION SELECT employee_id, name FROM employees WHERE region = 'West';

说明:这会返回东部和西部地区所有员工的 employee_idname,并去重重复记录。

8. HAVING 子句

HAVINGGROUP BY 后用来过滤结果集的条件语句。它与 WHERE 的不同之处在于,WHERE 用于过滤行数据,而 HAVING 用于过滤聚合数据。

示例:统计每个部门员工数量,并只返回员工数大于5的部门
 

sql

复制代码

SELECT department_id, COUNT(employee_id) AS employee_count FROM employees GROUP BY department_id HAVING COUNT(employee_id) > 5;

说明:这个查询通过 HAVING 子句筛选出员工数大于5的部门。

9. 分区表和分区查询(Partitioned Tables)

在处理大规模数据时,分区表是一种非常有效的优化方法。通过分区,数据可以按某些标准(如日期、范围、列表等)进行分割,这样可以提高查询的效率。

示例:基于日期的分区查询
 

sql

复制代码

CREATE TABLE sales ( sales_id INT, sale_date DATE, amount DECIMAL(10, 2) ) PARTITION BY RANGE (YEAR(sale_date)) ( PARTITION p2019 VALUES LESS THAN (2020), PARTITION p2020 VALUES LESS THAN (2021), PARTITION p2021 VALUES LESS THAN (2022) );

说明:将 sales 表按年份进行分区,能够提高按年份查询的效率。

10. 并行查询(Parallel Query Execution)

对于大数据量的查询,使用并行执行可以显著提高查询性能。并行查询通常在数据库配置和优化上需要一些技巧。

示例:在 PostgreSQL 中启用并行查询
 

sql

复制代码

SET max_parallel_workers_per_gather = 4;

说明:这个设置允许查询并行执行,增加执行的效率。

11. 优化查询(Query Optimization)

编写高效的SQL查询是提高数据库性能的关键。以下是几个优化技巧:

  • 避免在 WHERE 子句中使用 OROR 会导致扫描更多的行,最好使用 INUNION ALL 替代。
  • 避免在 WHERE 子句中使用函数:例如,避免 WHERE YEAR(order_date) = 2023,这会导致索引失效。
  • 使用合适的索引:确保查询中的筛选条件、连接条件和排序条件都有适当的索引支持。
  • 减少子查询的使用:尽量避免使用复杂的嵌套查询,可以通过连接或临时表来代替。

总结

掌握高级SQL技巧不仅能帮助你写出更复杂的查询,还能帮助你提高查询效率,优化数据库性能。你可以通过使用窗口函数、递归查询、条件聚合等技巧来处理复杂的业务逻辑,同时通过索引优化、分区表等技术提升查询性能。在实际开发中,要根据数据量、查询需求和性能要求灵活选择和使用这些技巧。

更多内容可以访问我的博客 https://ai.tmqcjr.com


http://www.kler.cn/a/453033.html

相关文章:

  • 鸿蒙之路的坑
  • Java开发经验——数据库开发经验
  • Educational Codeforces Round 173 (Rated for Div. 2)
  • 【Compose multiplatform教程08】【组件】Text组件
  • mac_录屏
  • 一文大白话讲清楚javascript单点登录
  • 《Java 与 Deeplearning4j:开启深度学习高效训练之旅》
  • 电脑缺失msvcp120.dll怎么弄?msvcp120.dll丢失的多个解决方法
  • 贪心算法解决用最少数量的箭引爆气球问题
  • 【Linux】linux系统修改磁盘 inode个数
  • Nginx配置:如何在一个域名下运行两个网站
  • Unity 6 中的新增功能
  • 【数据可视化复习方向】
  • MySQL的索引失效的原因有那些
  • 企业台账系统|Java|SSM|VUE| 前后端分离
  • 【华为OD-E卷-最多提取子串数目 100分(python、java、c++、js、c)】
  • 《Vue进阶教程》(12)ref的实现详细教程
  • 高级网络工程师需要不断的学习和实践,保持对技术发展的敏锐性和洞察力,同时能够在复杂环境中解决问题和推动创新。
  • <代码随想录> 算法训练营-2024.12.19
  • uniapp+vue 前端防多次点击表单,防误触多次请求方法。
  • 解决uniapp APP端切换横竖屏,页面排版崩溃问题
  • 手机IP地址:定义、查看与切换方法
  • 地理数据库Telepg面试内容整理-分布式与高可用
  • 网络安全 | 云计算中的数据加密与访问控制
  • Java学习笔记(15)——面向对象编程
  • 一个基于Rust适用于 Web、桌面、移动设备等的全栈应用程序框架