高级 SQL 技巧讲解

在这里插## 标题入图片描述

大家好,我是程序员小羊!

前言:

SQL(结构化查询语言)是管理和操作数据库的核心工具。从基本的查询语句到复杂的数据处理,掌握高级 SQL 技巧不仅能显著提高数据分析的效率,还能解决业务中的复杂问题。本文将深入探讨一些高级 SQL 技巧,包括窗口函数、复杂联结、CTE(公用表表达式)、递归查询、动态 SQL、性能优化等。


一、窗口函数(Window Functions)

窗口函数是一种强大的分析工具,能够在不改变原始数据行的情况下进行聚合运算和排名操作。

1. 基本语法

窗口函数通常与关键字 OVER() 一起使用,用于指定窗口范围。

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

解释

  • RANK():对每个部门(department_id)内的员工按薪资从高到低排名。
  • PARTITION BY:指定分组范围。
  • ORDER BY:定义排序逻辑。
2. 常用窗口函数
  • 排名函数ROW_NUMBER()RANK()DENSE_RANK() 用于对数据分组并排序。
  • 聚合函数SUM()AVG()COUNT() 等可以按分组计算累计值。
  • 滑动窗口计算:使用 ROWS BETWEENRANGE BETWEEN 定义滑动范围,如计算滚动平均值:
    SELECT order_date, customer_id, SUM(order_amount) OVER (PARTITION BY customer_id ORDER BY order_date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS rolling_sum
    FROM orders;
    

二、复杂联结(Complex Joins)

SQL 中的联结是数据处理的核心之一,高级 SQL 技巧往往体现在复杂联结的使用上。

1. 多表联结

当涉及多个表时,联结逻辑需要更清晰,避免数据重复或遗漏:

SELECT a.customer_name, b.order_id, c.product_name
FROM customers a
JOIN orders b ON a.customer_id = b.customer_id
JOIN products c ON b.product_id = c.product_id
WHERE c.category = 'Electronics';

解释:多表联结根据外键关系查询数据,例如查询购买电子产品的客户信息。

2. 自联结(Self Join)

自联结用于将一个表与自身进行关联,常用于层级数据查询:

SELECT e1.employee_id AS employee, e2.employee_id AS manager
FROM employees e1
LEFT JOIN employees e2 ON e1.manager_id = e2.employee_id;

解释:查询员工及其直接经理的信息。

3. 交叉联结(Cross Join)

交叉联结生成笛卡尔积,适用于所有组合的情况。

SELECT a.customer_name, b.product_name 
FROM customers a
CROSS JOIN products b;

注意:在实际使用中,需要限制结果集以免数据过多。


三、公用表表达式(CTE)

CTE 是提升代码可读性的重要工具,尤其在需要多步查询时表现出色。

1. 基本用法
WITH CTE_sales AS (SELECT employee_id, SUM(sale_amount) AS total_salesFROM salesGROUP BY employee_id
)
SELECT * 
FROM CTE_sales 
WHERE total_sales > 10000;

解释

  • WITH 定义 CTE 子查询,为后续查询提供简化视图。
  • 适合复杂查询分步骤实现。
2. 嵌套 CTE

可以通过嵌套多个 CTE 来处理复杂逻辑:

WITH CTE_orders AS (SELECT customer_id, SUM(order_amount) AS total_amount FROM orders GROUP BY customer_id
),
CTE_high_spenders AS (SELECT customer_id FROM CTE_orders WHERE total_amount > 10000
)
SELECT * 
FROM customers 
WHERE customer_id IN (SELECT customer_id FROM CTE_high_spenders);

四、递归查询

递归查询主要用于处理树形结构或分层数据。

1. 递归 CTE
WITH RECURSIVE employee_hierarchy AS (SELECT employee_id, manager_id, 1 AS levelFROM employeesWHERE manager_id IS NULLUNION ALLSELECT e.employee_id, e.manager_id, h.level + 1FROM employees eJOIN employee_hierarchy h ON e.manager_id = h.employee_id
)
SELECT * 
FROM employee_hierarchy;

解释

  • RECURSIVE 允许 CTE 自身引用。
  • 此例从顶级经理开始,递归查找所有下属及其层级关系。

五、动态 SQL

动态 SQL 允许根据输入动态生成查询,常用于存储过程或复杂查询中。

1. 动态拼接 SQL

在某些情况下需要根据用户输入生成动态 SQL:

DECLARE @sql NVARCHAR(MAX);
SET @sql = 'SELECT * FROM ' + @table_name + ' WHERE ' + @column_name + ' = @value';
EXEC sp_executesql @sql, N'@value NVARCHAR(100)', @value = 'example';

注意:确保输入经过验证,避免 SQL 注入风险。


六、性能优化技巧

SQL 性能优化对于处理大规模数据尤为重要。以下是一些常用的优化技巧:

1. 索引的使用
  • 单列索引与复合索引:根据查询条件创建合适的索引。例如:
    CREATE INDEX idx_customer_name ON customers (customer_name);
    
  • 避免全表扫描:通过索引提高过滤和排序的效率。
2. 分析执行计划

通过 EXPLAIN 或类似工具分析查询执行计划,定位瓶颈:

EXPLAIN SELECT * FROM orders WHERE customer_id = 1;
3. 避免不必要的复杂查询
  • 减少嵌套查询:使用联结替代子查询,提高效率。
  • 选择性查询:仅查询必要的列,避免使用 SELECT *
4. 分区与分片

对于大表,可以使用分区优化查询性能:

CREATE TABLE orders_partitioned (order_id INT,customer_id INT,order_date DATE
)
PARTITION BY RANGE (order_date) (PARTITION p1 VALUES LESS THAN ('2024-01-01'),PARTITION p2 VALUES LESS THAN ('2025-01-01')
);
5. 缓存查询结果

对于频繁使用的查询结果,可以缓存到中间表或物化视图中:

CREATE MATERIALIZED VIEW recent_orders AS 
SELECT * 
FROM orders 
WHERE order_date > CURRENT_DATE - INTERVAL '30 days';

七、事务管理

1. 事务的基本操作

SQL 中的事务保证数据操作的一致性:

BEGIN TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;
UPDATE accounts SET balance = balance + 100 WHERE account_id = 2;
COMMIT;

注意:在多步操作中加入 ROLLBACK 逻辑处理失败场景。

2. 隔离级别的选择

根据业务需求选择合适的隔离级别:

  • READ UNCOMMITTED:允许脏读,性能最高。
  • READ COMMITTED:禁止脏读,默认级别。
  • REPEATABLE READ:避免不可重复读。
  • SERIALIZABLE:完全隔离,性能最低。

总结

高级 SQL 技巧涵盖了从分析、建模到性能优化的方方面面。通过窗口函数进行复杂分析、使用 CTE 提高可读性、递归查询处理层级数据、动态
SQL
提高灵活性,开发者能够高效解决业务中的各种复杂需求。同时,关注性能优化和事务管理是处理大规模数据时不可忽视的关键环节。掌握这些高级技巧,能让你在数据处理中更加得心应手,充分发挥
SQL 的强大能力。

结尾

今天这篇文章就到这里了,大厦之成,非一木之材也;大海之阔,非一流之归也。感谢大家观看本文

在这里插入图片描述

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android okhttp 网络链接各阶段监控

步骤 1: 添加依赖 在项目的 build.gradle 文件中,添加 OkHttp 依赖: implementation com.squareup.okhttp3:okhttp:4.11.0 步骤 2: 创建自定义的 EventListener 创建一个自定义的 EventListener 类: import android.util.Log import okht…

springboot高校毕业生实习及就业去向信息管理系统

摘 要 高校毕业生实习及就业去向信息管理管理系统采用B/S架构,数据库是MySQL。网站的搭建与开发采用了先进的java进行编写,使用了springboot框架。该系统从三个对象:由管理员和学生、企业信息来对系统进行设计构建。主要功能包括&#xff1a…

网络安全概论——网络安全基础

一、网络安全引言 信息安全的四个属性(信息安全的基本目标 ) 保密性:信息不会被泄露给非授权用户完整性:保证数据的一致性可用性:合法用户不会被拒绝服务合法使用:不会被非授权用户或以非授权的方式使用 二、网络安…

【Unity基础】认识Unity中的包

Unity中的包是一个核心概念,像Unity本身的功能的扩展,或者项目中资源的管理,都是通过包的形式来实现的。 一、什么是包? 一个包包含满足您项目各种需求的功能。这可以包括编辑器安装过程中附带的任何核心Unity功能,也…

【从零开始的LeetCode-算法】3354. 使数组元素等于零

给你一个整数数组 nums 。 开始时,选择一个满足 nums[curr] 0 的起始位置 curr ,并选择一个移动 方向 :向左或者向右。 此后,你需要重复下面的过程: 如果 curr 超过范围 [0, n - 1] ,过程结束。如果 nu…

VUE+SPRINGBOOT实现邮箱注册、重置密码、登录功能

随着互联网的发展,网站用户的管理、触达、消息通知成为一个网站设计是否合理的重要标志。目前主流互联网公司都支持手机验证码注册、登录。但是手机短信作为服务端网站是需要付出运营商通信成本的,而邮箱的注册、登录、重置密码,无疑成为了这…

ChatGPT Search VS Kimi探索版:AI搜索哪家强?!

大家好,我是木易,一个持续关注AI领域的互联网技术产品经理,国内Top2本科,美国Top10 CS研究生,MBA。我坚信AI是普通人变强的“外挂”,专注于分享AI全维度知识,包括但不限于AI科普,AI工…

【网络系统管理】Centos7——配置主从mariadb服务器案例(下半部分)

【网络系统管理】Centos7——配置主从mariadb服务器案例-CSDN博客 接上个文档,我们已经完成了主服务器创建数据库备服务器可以看到 一、在DBMS2查看信息 File,Position这两个字段的数据要记好,等一下需要用到 show master status; 二、在…

定长滑动窗口(LeetCode——1423.可获得的最大点数)

题目 . - 力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/maximum-points-you-can-obtain-from-cards 几张卡牌 排成一行…

ubuntu20.04如何升级python3.8到python3.10

主要参考了这两个链接: 如何在Ubuntu 20.04安装Python 3.10 | myfreaxhttps://www.myfreax.com/how-to-install-python-3-10-on-ubuntu-20-04/#:~:text%E5%9C%A8%E8%B0%83%E8%AF%95%E5%92%8C%E5%85%B6%E4%BB%96%E5%B7%A5%E5%85%B7%E4%B8%AD%E4%BD%BF%E7%94%A8%E7%B…

JDK安装和Linux常见设置详细版教程

一、Linux的常见设置 1、设置静态IP vi /etc/sysconfig/network-scripts/ifcfg-ens33 如何查看自己的虚拟机的网关: 完整的配置(不要拷贝我的): TYPE"Ethernet" PROXY_METHOD"none" BROWSER_ONLY"no&…

【Visual Studio系列教程】如何在 VS 上编程?

上一篇博客中,我们介绍了《什么是 Visual Studio?》。本文,我们来看第2篇《如何在 VS 上编程?》。阅读本文大约10 分钟。我们会向文件中添加代码,了解 Visual Studio 编写、导航和了解代码的简便方法。 本文假定&…

python: generator model using sql server 2019

設計或生成好數據庫,可以生成自己設計好的框架項目 # encoding: utf-8 # 版权所有 :2024 ©涂聚文有限公司 # 许可信息查看 :言語成了邀功盡責的功臣,還需要行爲每日來值班嗎 # 描述: : 生成实体 # Author …

【Rabbitmq篇】RabbitMQ⾼级特性----消息确认

目录 前言: 一.消息确认机制 • ⾃动确认 • ⼿动确认 手动确认方法又分为三种: 二. 代码实现(spring环境) 配置相关信息: 1). AcknowledgeMode.NONE 2 )AcknowledgeMode.AUTO 3&…

【Pikachu】SSRF(Server-Side Request Forgery)服务器端请求伪造实战

尽人事以听天命 1.Server-Side Request Forgery服务器端请求伪造学习 SSRF(服务器端请求伪造)攻击的详细解析与防范 SSRF(Server-Side Request Forgery,服务器端请求伪造) 是一种安全漏洞,它允许攻击者通…

鸿蒙NEXT自定义组件:太极Loading

【引言】(完整代码在最后面) 本文将介绍如何在鸿蒙NEXT中创建一个自定义的“太极Loading”组件,为你的应用增添独特的视觉效果。 【环境准备】 电脑系统:windows 10 开发工具:DevEco Studio NEXT Beta1 Build Vers…

JSONObject jsonObject = JSON.parseObject(json);

是用于将一个 JSON 格式的字符串解析为一个 JSONObject 对象的语句。具体来说: JSON.parseObject(json): 作用: JSON 是 FastJSON 库提供的一个工具类。parseObject 方法可以将 JSON 格式的字符串(例如:{"key1&qu…

python成绩分级 2024年6月python二级真题 青少年编程电子学会编程等级考试python二级真题解析

目录 python成绩分级 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序代码 四、程序说明 五、运行结果 六、考点分析 七、 推荐资料 1、蓝桥杯比赛 2、考级资料 3、其它资料 python成绩分级 2024年6月 python编程等级考试二级编程题 一、题目要求 …

【面试题】接口怎么测试?如何定位前后端的Bug?

接口怎么测试? 接口测试用来验证不同软件组件之间的交互是否正常。包括验证数据传输,参数传递,我在多个项目中有过测试接口的经验。(… 当进行接口测试时,会使用Postman和Python的Requests库。首先根据接口文档设计测…

.net6.0(.net Core)读取 appsettings.json 配置文件

① 新项目中创建名为 appsettings.json 的 json文件,内容为: {//数据库连接字符串:"ConnectionString": {"DBconn": "server127.0.0.1;databasedb;uidsa;pwd123456;Timeout600;EncryptTrue;TrustServerCertificateTrue;"…