高级 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 BETWEEN
或RANGE 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 的强大能力。
结尾
今天这篇文章就到这里了,大厦之成,非一木之材也;大海之阔,非一流之归也。感谢大家观看本文
相关文章:

高级 SQL 技巧讲解
大家好,我是程序员小羊! 前言: SQL(结构化查询语言)是管理和操作数据库的核心工具。从基本的查询语句到复杂的数据处理,掌握高级 SQL 技巧不仅能显著提高数据分析的效率,还能解决业务中的复…...

浅论AI大模型在电商行业的发展未来
随着人工智能(AI)技术的快速发展,AI大模型在电商行业中扮演着越来越重要的角色。本文旨在探讨AI大模型如何赋能电商行业,包括提升销售效率、优化用户体验、增强供应链管理等方面。通过分析AI大模型在电商领域的应用案例和技术进展…...

【python笔记03】《类》
文章目录 面向对象基本概念对象的概念类的概念 类的定义类的创建(实例的模板)类的实例化--获取对象对象方法中的self关键字面试题请描述什么是对象,什么是类。请观阅读如下代码,判断是否能正常运行,如果不能正常运行&a…...

Flutter 应用在真机上调试的流程
在真机上调试 Flutter 应用的方法有很多,可以使用 USB 数据线连接设备到电脑进行调试,也可以通过无线方式进行 Flutter 真机调试。 1. 有线调试 设备准备 启用开发者模式: Android:进入 设置 > 关于手机,连续点击…...

以太坊基础知识结构详解
以太坊的历史和发展 初创阶段 2013年:Vitalik Buterin 发表了以太坊白皮书,提出了一个通用的区块链平台,不仅支持比特币的货币功能,还能支持更复杂的智能合约。2014年:以太坊项目启动,进行了首次ICO&…...

安全见闻(完整版)
目录 安全见闻1 编程语言和程序 编程语言 函数式编程语言: 数据科学和机器学习领域: Web 全栈开发: 移动开发: 嵌入式系统开发: 其他: 编程语言的方向: 软件程序 操作系统 硬件设备…...

LeetCode100之反转链表(206)--Java
1.问题描述 给你单链表的头节点 head ,请你反转链表,并返回反转后的链表 示例1 输入:head [1,2,3,4,5] 输出:[5,4,3,2,1] 示例2 输入:head [1,2] 输出:[2,1] 示例3 输入:head [] 输…...

牛客周赛第一题2024/11/17日
链接:登录—专业IT笔试面试备考平台_牛客网 来源:牛客网 时间限制:C/C/Rust/Pascal 1秒,其他语言2秒 空间限制:C/C/Rust/Pascal 256 M,其他语言512 M 64bit IO Format: %lld 题目描述 小红这天来到了三…...

麒麟Server下安装东方通TongLINK/Q
环境 系统:麒麟Server SP3 2403 应用:TLQ8.1(Install_TLQ_Standard_Linux2.6.32_x86_64_8.1.17.0.tar.gz) 安装Server 将文件解压到/usr/local/tlq。 cd /opt/tlq/ mkdir /usr/local/tlq/ tar -zxvf Install_TLQ_Standard_Linux2.6.32_x86_64_8.1.1…...

BERT的中文问答系统33
我们在现有的代码基础上增加网络搜索的功能。我们使用 requests 和 BeautifulSoup 来从百度搜索结果中提取信息。以下是完整的代码,包括项目结构、README.md 文件以及所有必要的代码。 项目结构 xihe241117/ ├── data/ │ └── train_data.jsonl ├── lo…...

Ubuntu下的Eigen库的安装及基本使用教程
一、Eigen库介绍 简介 Eigen [1]目前最新的版本是3.4,除了C标准库以外,不需要任何其他的依赖包。Eigen使用的CMake建立配置文件和单元测试,并自动安装。如果使用Eigen库,只需包特定模块的的头文件即可。 基本功能 Eigen适用范…...

【spring 】Spring Cloud Gateway 的Filter学习
介绍和使用场景 Spring Cloud Gateway 是一个基于 Spring Framework 5 和 Project Reactor 的 API 网关,它旨在为微服务架构提供一种简单而有效的方式来处理请求路由、过滤、限流等功能。在 Spring Cloud Gateway 中,Filter 扮演着非常重要的角色&#…...

每秒交易数(Transactions Per Second:TPS)详细拆解
每秒交易数(TPS)是指计算机网络每秒可以处理的交易数量。TPS是衡量不同区块链和其他计算机系统速度的关键指标。然而,TPS并不是用来衡量区块链速度的唯一指标。许多人认为,虽然TPS很重要,但最终性实际上是一个更重要的…...

【初阶数据结构与算法】链表刷题之链表分割、相交链表、环形链表1、环形链表I、环形链表II
文章目录 一、链表分割二、相交链表三、环形链表I四、环形链表|| 一、链表分割 题目链接:https://www.nowcoder.com/practice/0e27e0b064de4eacac178676ef9c9d70 我们来看看链表分割的题目描述和它给出的函数: 这个题虽然是以C形式来做࿰…...

【STL】set,multiset,map,multimap的介绍以及使用
关联式容器 在C的STL中包含序列式容器和关联式容器 1.关联式容器:它里面存储的是元素本身,其底层是线性序列的数据结构,比如:vector,list,deque,forward_list(C11)等 2.关联式容器里面储存的…...

新能源二手车交易量有望破百万,二手车市场回暖了吗?
这些年,伴随着新能源汽车市场的高速发展,各种新能源车的二手车也在逐渐增加,不过之前的二手车市场相对比较冷清,就在最近一则新闻传出新能源二手车交易量有望破百万,二手车市场这是回暖了吗? 一、新能源二手…...

哈佛商业评论 | 项目经济的到来:组织变革与管理革新的关键
在21世纪,项目经济(Project Economy)逐步取代传统运营,成为全球经济增长的核心动力。项目已不再是辅助工具,而是推动创新和变革的重要载体。然而,只有35%的项目能够成功,显示出项目管理领域存在巨大的改进空间。本文将详细探讨项目经济的背景、项目管理的挑战,以及适应…...

web浏览器环境下使用window.open()打开PDF文件不是预览,而是下载文件?
如果你使用 window.open() 方法打开 PDF 文件,但浏览器不是预览而是下载文件,这可能是由于以下几个原因: 服务器配置:服务器可能将 PDF 文件配置为下载而不是预览。例如,服务器可能设置了 Content-Disposition 响应头…...

【GeekBand】C++设计模式笔记12_Singleton_单件模式
1. “对象性能” 模式 面向对象很好地解决了 “抽象” 的问题, 但是必不可免地要付出一定的代价。对于通常情况来讲,面向对象的成本大都可以忽略不计。但是某些情况,面向对象所带来的成本必须谨慎处理。典型模式 SingletonFlyweight 2. Si…...

Pyhon基础数据结构(列表)【蓝桥杯】
a [1,2,3,4,5] a.reverse() print("a ",a) a.reverse() print("a ",a)# 列表 列表(list)有由一系列按照特定顺序排序的元素组成 列表是有顺序的,访问任何元素需要通过“下标访问” 所谓“下标”就是指元素在列表从左…...

Linux篇(权限管理命令)
目录 一、权限概述 1. 什么是权限 2. 为什么要设置权限 3. Linux中的权限类别 4. Linux中文件所有者 4.1. 所有者分类 4.2. 所有者的表示方法 属主权限 属组权限 其他权限 root用户(超级管理员) 二、普通权限管理 1. ls查看文件权限 2. 文件…...

深入理解 Spark 中的 Shuffle
Spark 的介绍与搭建:从理论到实践_spark环境搭建-CSDN博客 Spark 的Standalone集群环境安装与测试-CSDN博客 PySpark 本地开发环境搭建与实践-CSDN博客 Spark 程序开发与提交:本地与集群模式全解析-CSDN博客 Spark on YARN:Spark集群模式…...

leetcode-8-字符串转整数
题解: 代码:...

SQL注入注入方式(大纲)
SQL注入注入方式(大纲) 常规注入 通常没有任何过滤,直接把参数存放到SQL语句中。 宽字节注入 GBK 编码 两个字节表示一个字符ASCII 编码 一个字节表示一个字符MYSQL默认字节集是GBK等宽字节字符集 原理: 设置MySQL时错误配置…...

OpenCV基础(1)
1.图像读写与窗口显示 1.1.imread读取图像文件 Mat cv::imread(const string &filename,int flags IMREAD_COLOR); filename:要读取的图像文件名flags:读取模式,可以从枚举cv::ImreadModes中取值,默认取值是IMREAD_COLOR&am…...

【freertos】FreeRTOS信号量的介绍及使用
FreeRTOS信号量 一、概述二、PV原语三、函数接口1.创建一个计数信号量2.删除一个信号量3.信号量释放4.在中断释放信号量5.获取一个信号量,可以是二值信号量、计数信号量、互斥量。6.在中断获取一个信号量,可以是二值信号量、计数信号量7.创建一个二值信号…...

React Native 全栈开发实战班 - 图片加载与优化
在移动应用中,图片加载与优化 是提升用户体验和减少资源消耗的重要环节。图片加载不当可能导致应用卡顿、内存泄漏甚至崩溃。本章节将介绍 React Native 中常用的图片加载方法,包括 Image 组件的使用、第三方图片加载库(如 react-native-fast…...

Golang云原生项目:—实现ping操作
熟悉报文结构 ICMP校验和算法: 报文内容,相邻两个字节拼接到一起组成一个16bit数,将这些数累加求和若长度为奇数,则将剩余一个字节,也累加求和得出总和之后,将和值的高16位与低16位不断求和,直…...

mysql如何查看当前事务的事务id
-- 开启一个事务,但不执行写操作 START TRANSACTION; -- 查询 InnoDB 事务信息 SELECT * FROM information_schema.innodb_trx;在 MySQL 的 MVCC (多版本并发控制) 中,事务 ID (Transaction ID) 是由 InnoDB 存储引擎分配的,它的分配机制与事…...

在linux里如何利用vim对比两个文档不同的行数
在Linux中,可以使用vimdiff命令来对比两个文档中不同的行。首先确保你的系统中安装了vim编辑器。 打开终端,使用以下命令来启动vimdiff: vimdiff file1 file2 这里file1和file2是你想要对比的两个文件的路径。 vimdiff会以并排方式打开两…...