Mysql-窗口函数二

news2024/12/29 7:56:08

文章目录

  • 1. 前百分之N的问题 排名 row_number
    • 1.1 需求
    • 1.2 准备工作
    • 1.3 分析
    • 1.4 实现
  • 2. 前百分之N的问题 ntile
    • 2.1 介绍
    • 2.2 语法
      • 2.2.1 示例
      • 2.2.2 结果示例
      • 2.2.3 注意事项
    • 2.3 需求
    • 2.4 分析
    • 2.5 实现
  • 3. 前百分之N的问题 百分比 PERCENT_RANK
    • 3.1 语法
      • 3.1.1 示例
      • 3.1.2 注意事项
    • 3.2 需求
    • 3.3 实现
  • 4. 偏移函数: 求环比增长率
    • 4.1 需求
    • 4.2 语法
    • 4.3 示例
    • 4.4 解释
    • 4.5 分析
    • 4.6 实现
    • 4.6 总结

1. 前百分之N的问题 排名 row_number

1.1 需求

  • 用户访问次数表,包含用户编号、用户类型、访问次数。
  • 要求在剔除访问次数前20%的用户后得到每类用户的平均访问次数。

1.2 准备工作

create table user_visits (
    user_id int,
    user_type varchar(32),
    visit_count int
)
;

insert into user_visits
values
(10, 'A', 352),
(6, 'C', 209),
(7, 'C', 110),
(4, 'E', 101),
(2, 'B', 53),
(20, 'A', 53),
(11, 'C', 33),
(1, 'A', 30),
(9, 'E', 29),
(8, 'B', 6)
;

1.3 分析

在这里插入图片描述
在这里插入图片描述

1.4 实现

with t1 as(select user_id, user_type, visit_count,
       row_number() over (order by visit_count desc) as rn
from user_visits)
select distinct user_type,
       round(avg(visit_count) over(partition by user_type),1) as avg_cnt
from t1 where rn>(select count(*) from user_visits) * 0.2;

在这里插入图片描述

2. 前百分之N的问题 ntile

2.1 介绍

NTILE 是一个窗口函数,用于将查询结果划分为指定数量的分组,并为每个分组分配一个组号。这在分析数据时非常有用,尤其是需要对数据进行分组或均匀分配时。

2.2 语法

NTILE(num_buckets) OVER (PARTITION BY column ORDER BY column)
  • num_buckets:要将数据划分的组数(桶数)。
  • PARTITION BY column:可选,用于按指定列对数据进行分区。
  • ORDER BY column:必需,用于指定每个分区内的排序。

2.2.1 示例

假设我们有一个包含学生成绩的表 student_scores,结构如下:
在这里插入图片描述
准备数据

-- 创建表
CREATE TABLE students_score (
  student_id INT PRIMARY KEY,
  name VARCHAR(255),
  score INT
);

-- 插入数据
INSERT INTO students_score (student_id, name, score) VALUES
(1, 'Alicia', 85),
(2, 'Robert', 90),
(3, 'Charles', 78),
(4, 'David', 92),
(5, 'Eva', 88);

将这些学生按分数划分为 3 组,并查看每个学生所属的组号。

SELECT
    student_id,
    name,
    score,
    NTILE(3) OVER (ORDER BY score DESC) AS group_number
FROM
    students_score;

2.2.2 结果示例

在这里插入图片描述
在这个例子中,NTILE(3) 将数据划分为 3 组,并根据分数的降序排序为每个学生分配一个组号。前两个最高分的学生被分配到第一组(组号1),接下来的两个学生被分配到第二组(组号2),而分数最低的学生被分配到第三组(组号3)。

2.2.3 注意事项

  • 如果不能均匀分配组,则较小编号的组可能会多出一行。例如,如果有 10 行数据和 3 组,则前两个组将有 4 行数据,最后一个组将有 2 行数据。
  • NTILE 通常用于数据分析场景,例如分配排名、分层抽样等。

2.3 需求

  • 用户访问次数表,包含用户编号、用户类型、访问次数。
  • 要求在剔除访问次数前20%的用户后得到每类用户的平均访问次数。
    在这里插入图片描述

2.4 分析

在这里插入图片描述

2.5 实现

with t1 as (
    select
        user_id, user_type, visit_count,
        ntile(10) over (order by visit_count desc) as nt
    from user_visits
)
select
    user_type,
    round(avg(visit_count), 1) as avg_visit
from t1
where t1.nt>2
group by user_type
order by user_type;

3. 前百分之N的问题 百分比 PERCENT_RANK

3.1 语法

PERCENT_RANK() 是 SQL 中的窗口函数,用于计算某行的百分比排名。这个函数在数据分析中常用于了解某一数据点在整体数据中的相对位置。百分比排名的取值范围是从 0 到 1,表示当前行在分区内的排名相对于分区内其他行的百分比位置。

PERCENT_RANK() OVER (PARTITION BY column ORDER BY column)
  • PARTITION BY column:可选,用于按指定列对数据进行分区。
  • ORDER BY column:必需,用于指定每个分区内的排序。
    PERCENT_RANK() 的计算方式是:
百分比排名 = (当前行的排名 - 1) / (分区内的行总数 - 1)

3.1.1 示例

假设我们有一个包含学生成绩的表 students_score,结构如下:
在这里插入图片描述
计算每个学生的百分比排名。

SELECT
    student_id,
    name,
    score,
    PERCENT_RANK() OVER (ORDER BY score DESC) as `percent_rank`
FROM
    students_score;

结果
在这里插入图片描述

3.1.2 注意事项

  • 排序顺序:PERCENT_RANK() 的计算依赖于 ORDER BY 子句指定的排序顺序。在上面的例子中,我们按照 score 降序排列,最高分的学生的 percent_rank 是 0。

  • 分区:如果使用了 PARTITION BY 子句,则 PERCENT_RANK() 会在每个分区内计算百分比排名,而不是在整个结果集上。

  • 相同值:在处理相同值时,PERCENT_RANK() 会为相同值分配相同的排名百分比。

  • 第一行和最后一行:第一行的 percent_rank 总是 0,而最后一行的 percent_rank 总是 1。

PERCENT_RANK() 常用于了解数据在分布中的相对位置,对于生成百分比排名或分位数分析非常有用。

3.2 需求

  • 用户访问次数表,包含用户编号、用户类型、访问次数。
  • 要求在剔除访问次数前20%的用户后得到每类用户的平均访问次数。
    在这里插入图片描述

3.3 实现

with t1 as (
    select
        user_id, user_type, visit_count,
        percent_rank() over (order by visit_count desc) as pr
    from user_visits
)
select
    user_type,
    round(avg(visit_count), 1) as avg_visit
from t1
where pr>0.2
group by user_type
order by user_type;

4. 偏移函数: 求环比增长率

4.1 需求

假设有一个销售数据表 sales,其中记录了每个月的销售额,想要计算每个月的销售额与上个月的销售额之间的变化。
在这里插入图片描述

4.2 语法

LAG() 是 SQL 中的一个窗口函数,用于从当前行向上偏移指定数量的行,并返回偏移行的值。它对于访问前面的行数据而不使用自连接非常有用,特别是在时间序列数据和累积计算中。

LAG(column, offset, default) OVER (PARTITION BY partition_column ORDER BY order_column)

参数解释:
参数解释

  • column: 这是你要获取前值的列。
  • offset: 向上偏移的行数。默认为1,表示返回前一行的值。
  • default: 当偏移行超出窗口范围时返回的默认值。如果没有指定,默认值为 NULL。
  • PARTITION BY partition_column: 可选项,用于指定分区列。在每个分区内独立计算 LAG 值。如果没有指定,整个结果集将视为一个分区。
  • ORDER BY order_column: 必需项,用于指定窗口函数处理数据的顺序。

4.3 示例

假设有一个包含月份销售数据的表 monthly_sales,其结构如下:
在这里插入图片描述
获取每个月的销售额,以及与前一个月销售额的差异。

SELECT
    month,
    sales,
    LAG(sales, 1) OVER (ORDER BY month) AS previous_sales,
    LAG(sales, 1, 666) OVER (ORDER BY month) AS previous_sales_2
FROM sales_data;

结果:
在这里插入图片描述

4.4 解释

  • LAG(sales, 1, 0) OVER (ORDER BY month): 该表达式获取前一个月的销售额。如果没有前一个月的数据(例如对于第一行),则返回默认值 0。
  • sales - previous_sales: 计算当前月与上月的销售额差异。

4.5 分析

在这里插入图片描述

4.6 实现

drop database if exists db_1;
create database db_1;
use db_1;

-- 创建表
CREATE TABLE sales_data (
    month VARCHAR(7) NOT NULL,
    sales INT NOT NULL,
    PRIMARY KEY (month)
);

-- 插入数据
INSERT INTO sales_data (month, sales) VALUES
('2023-01', 1000),
('2023-02', 1100),
('2023-03', 1050),
('2023-04', 1200),
('2023-05', 1150);

select * from sales_data;

# 目标: 求环比增长率 = (当前月销量 - 上一月销量) / 上一月销量 * 100
select
    month,
    sales,
    lag(sales, 1, 0) over(order by month) as lag_1_sales,
    # sales - (lag(sales, 1) over(order by month)) as diff,
    # (sales - (lag(sales, 1) over(order by month))) / (lag(sales, 1) over(order by month)) * 100 as rate,
    # round((sales - (lag(sales, 1) over(order by month))) / (lag(sales, 1) over(order by month)) * 100, 2) as rate_2,
    concat(round((sales - (lag(sales, 1) over(order by month))) / (lag(sales, 1) over(order by month)) * 100, 1), '%') as rate_3
from sales_data;

4.6 总结

- LAG(字段, [N], [M]):返回分区中当前行前第N行的指定字段的内容,如果没有,默认返回M
- LEAD(字段, [N], [M]):返回分区中当前行后第N行的指定字段的内容,如果没有,默认返回M

  • first_val(…)
  • last_val(…)
  • 注意:M和N可以省略,N默认为1,M默认为NULL。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

函数的练习

1.判断一个数是否为素数 代码如下&#xff1a; #include <stdio.h> int jum(int num) {int i 0;for (i 2;i < num;i){if (num % i 0){return 0;break;}}return 1; }void Jum1(int (*pf)(int)) {int num 0;printf("请输入操作数&#xff1a;");scanf_s…

声压、声强、响度之间的区别与联系

声压、声强、响度是声学中描述声音特性的重要概念&#xff0c;它们之间有一定的关系&#xff0c;但分别反映了不同的物理或感知特性。 1、声压&#xff08;Sound Pressure&#xff09; 声压是声波传播时在介质中引起的压力波动&#xff0c;通常以帕斯卡&#xff08;Pa&#x…

Windows电脑下载安装Kodcloud可道云结合内网穿透秒变私有网盘

文章目录 1.前言2. Kodcloud网站搭建2.1. Kodcloud下载和安装2.2 Kodcloud网页测试 3. cpolar内网穿透的安装和注册4. 本地网页发布4.1 Cpolar云端设置4.2 Cpolar本地设置 5. 公网访问测试6.结语 1.前言 本文主要为大家介绍一款国人自研的在线Web文件管理器可道云&#xff0c;…

苹果手机数据被抹除还能恢复吗?这两个方法强烈推荐

苹果手机数据被抹除还能恢复吗&#xff1f;我们在使用苹果手机时&#xff0c;有时由于误操作、系统故障或升级失败等原因&#xff0c;导致手机照片、备忘录、视频、联系人等数据被意外抹除。 面对这类情况&#xff0c;我们应该怎么办&#xff1f;下面牛小编给大家的分享2个方法…

CH07_数据绑定

第7章&#xff1a;数据绑定 本章目标 理解路由事件 掌握键盘输入事件 掌握鼠标输入事件 掌握多点触控输入事件 数据绑定概述 什么是数据绑定 ​ 将WPF中的至少一个带有依赖项属性的两个对象的两个属性进行绑定&#xff0c;使某一个依赖项属性可以更新和它绑定的属性的功…

奥尔特曼在X上发了颗“草莓” 网友疯狂猜测:这难道是GPT新模型?

ChatGPT开发商OpenAI的首席执行官山姆奥尔特曼&#xff08;Sam Altman&#xff09;在社交媒体X上发布了一张花园里自种草莓的照片后&#xff0c;引发了众多网友的热议&#xff0c;是否新的GPT模型即将上线&#xff1f; 周三&#xff08;8月7日&#xff09;&#xff0c;奥尔特曼…

海量数据处理商用短链接生成器平台 - 8

第十八章 短链服务-分库分表多维度查询解决方案《钻石玩法》 第1集 短链服务-短链URL跳转302跳转接口开发实战 简介&#xff1a; 短链URL 跳转302跳转接口开发实战 需求 接收一个短链码解析获取原始地址302进行跳转 编码实战 Controller Slf4j public class LinkApiControl…

搭建时空基底,建设“数字之城”

在这个日新月异的时代&#xff0c;数字技术正以前所未有的速度重塑我们的世界。今天&#xff0c;让我们一同深入探讨如何通过搭建时空基底&#xff0c;为“数字之城”的建设奠定坚实基础。 一、时空基底&#xff1a;数字之城的骨骼与脉络 所谓“时空基底”&#xff0c;是指结…

【vulnhub】DC-6靶机

靶机安装 下载地址&#xff1a;https://download.vulnhub.com/dc/DC-6.zip 运行靶机&#xff1a;VMware 信息收集 靶机扫描 nmap 192.168.93.0/24 端口扫描,根据80端口的信息&#xff0c;发现我们并不能直接访问靶机的web页面&#xff0c;和/wordy相关 nmap -A 192.168.9…

本地部署MySQL图形化管理工具phpMyAdmin结合内网穿透远程访问

文章目录 前言1. 安装MySQL2. 安装phpMyAdmin3. 修改User表4. 本地测试连接MySQL5. 安装cpolar内网穿透6. 配置MySQL公网访问地址7. 配置MySQL固定公网地址8. 配置phpMyAdmin公网地址9. 配置phpmyadmin固定公网地址 前言 本文主要介绍如何在群晖NAS安装MySQL与数据库管理软件p…

C++虚函数表、地址详解(x86/x64)

参考博文&#xff1a;c虚函数表、地址详解-CSDN博客 本文在上述博文的基础上&#xff0c;补充了x64下的验证代码。 一.什么是虚函数表&#xff0c;它有什么特点&#xff1f; 虚函数大家都知道是基本用于实现多态的&#xff0c;当父类指针指向子类对象的时候&#xff0c;如何确…

国自然即将放榜,还没消息是不是就凉了?

本周投稿推荐 SCI&EI • 医学与心理学&#xff0c;纯正刊&#xff08;基本不拒稿&#xff09; • 1区计算机水刊&#xff0c;3.5-4.0&#xff08;1个月录用&#xff09; • 2区-Top水刊&#xff0c;2.0-3.0&#xff08;沾边可录&#xff09; EI • 各领域沾边均可&am…

超分辨率重建——冠军队EDVR视频超分网络训练自己数据集与推理测试(详细图文教程)

&#x1f4aa; 专业从事且热爱图像处理&#xff0c;图像处理专栏更新如下&#x1f447;&#xff1a; &#x1f4dd;《图像去噪》 &#x1f4dd;《超分辨率重建》 &#x1f4dd;《语义分割》 &#x1f4dd;《风格迁移》 &#x1f4dd;《目标检测》 &#x1f4dd;《暗光增强》 &a…

LeetCode刷题笔记第17题:电话号码的字母组合

LeetCode刷题笔记第17题&#xff1a;电话号码的字母组合 题目&#xff1a; 想法&#xff1a; 先构建手机号码的字典&#xff0c;利用回溯的思想&#xff0c;组合数字对应的字母&#xff0c;代码如下&#xff1a; class Solution:def letterCombinations(self, digits: str) …

Animate软件基本概念:元件(影片剪辑、图形、按钮)

这一篇是说明Animate软件中常见的几种元件类型的定义。 FlashASer&#xff1a;AdobeAnimate2021软件零基础入门教程https://zhuanlan.zhihu.com/p/633230084 FlashASer&#xff1a;实用的各种Adobe Animate软件教程https://zhuanlan.zhihu.com/p/675680471 FlashASer&#x…

数据结构:栈与队列OJ题

目录 前言 一、用栈实现队列 二、用队列实现栈 三、括号匹配问题 前言 前面讲了栈和队列的基础知识&#xff0c;今天来巩固一下加深理解&#xff0c;这里说明一下&#xff0c;因为现在都是在用C语言写&#xff0c;这些OJ题里都要用到前面实现栈和队列的代码&#xff0c;每道题…

Java 自定义注解 笔记总结(油管)

Java系列文章目录 IDEA使用指南 Java泛型总结&#xff08;快速上手详解&#xff09; Java Lambda表达式总结&#xff08;快速上手详解&#xff09; Java Optional容器总结&#xff08;快速上手图解&#xff09; Java 自定义注解笔记总结&#xff08;油管&#xff09; Jav…

AI时代,我们还可以做什么?

最近看了本书&#xff0c;书名叫做《拐点&#xff1a;站在 AI 颠覆世界的前夜》&#xff0c;作者是万维钢。 本想着看完后&#xff0c;就能掌握一整套 AI 技巧&#xff0c;结果——竟然学了很多道理。 这本书讨论了以下话题&#xff1a; 我们该怎么理解这个 AI 大时代的哲学&am…

思迈特发布全新AI应用,Smartbi AIChat白泽来了

8月8日&#xff0c;Smartbi AIChat白泽新品发布会在云端与大家如期美好相约&#xff0c;共同见证思迈特软件基于AI Agent的新一代智能BI应用落地的全新里程碑时刻。 思迈特软件创始人吴华夫和产品总监杨礼显先后围绕商业智能行业发展趋势、产品demo show、技术原理及未来规划展…

Mysql,用户名重复,无法调用问题

问题描述&#xff1a; 我电脑的数据库用户名是&#xff0c;root。 因为经常需要帮别人封装程序&#xff0c;所以需要在我本机跑通别人的程序。有的程序里面也涉及到数据库&#xff0c;用户名也是&#xff0c;root&#xff0c;但是密码与我本机的不同。 之前我会修改我用户名…