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

做外贸英文网站网站设计步骤及图解

做外贸英文网站,网站设计步骤及图解,手机网站小程序,咨询网站源码MySQL 8.0窗口函数详解:用测试数据彻底掌握高级查询 窗口函数是MySQL 8.0最值得关注的新特性之一,它能大幅简化复杂分析查询。本文通过可直接运行的测试数据实战案例,系统讲解窗口函数的核心用法,助你快速掌握这一利器。 一、环境…

MySQL 8.0窗口函数详解:用测试数据彻底掌握高级查询

窗口函数是MySQL 8.0最值得关注的新特性之一,它能大幅简化复杂分析查询。本文通过可直接运行的测试数据+实战案例,系统讲解窗口函数的核心用法,助你快速掌握这一利器。


一、环境准备:测试数据表

创建测试表并插入数据

-- 创建员工销售表
CREATE TABLE employee_sales (emp_id INT,emp_name VARCHAR(50),department VARCHAR(50),sale_date DATE,amount DECIMAL(10,2)
);-- 插入测试数据
INSERT INTO employee_sales VALUES
(1, '张三', '技术部', '2023-01-05', 5000),
(2, '李四', '销售部', '2023-01-10', 8000),
(3, '王五', '技术部', '2023-01-15', 3000),
(1, '张三', '技术部', '2023-02-02', 7000),
(4, '赵六', '销售部', '2023-02-10', 12000),
(2, '李四', '销售部', '2023-02-12', 9000),
(5, '陈七', '行政部', '2023-03-01', 1500);

二、窗口函数核心概念

1. 窗口函数 vs 聚合函数

对比维度窗口函数普通聚合函数
结果行数保持原表行数按分组聚合减少行数
使用场景计算排名、移动平均等分析需求求总和、平均值等统计需求
典型函数ROW_NUMBER(), SUM() OVER()SUM(), AVG()

2. 核心语法结构

SELECT 字段列表,窗口函数() OVER ([PARTITION BY 分组字段][ORDER BY 排序字段][ROWS/RANGE 窗口范围]) AS 别名
FROM 表名;

三、7种常用窗口函数实战

案例1:ROW_NUMBER() - 生成连续排名

-- 按部门分组,给每个员工的销售额排名
SELECT emp_name,department,amount,ROW_NUMBER() OVER (PARTITION BY department ORDER BY amount DESC) AS dept_rank
FROM employee_sales;

输出结果

| emp_name | department | amount | dept_rank |
|----------|------------|--------|-----------|
| 张三     | 技术部     | 7000   | 1         |
| 张三     | 技术部     | 5000   | 2         |
| 王五     | 技术部     | 3000   | 3         |
| 赵六     | 销售部     | 12000  | 1         |
| 李四     | 销售部     | 9000   | 2         |
| 李四     | 销售部     | 8000   | 3         |
| 陈七     | 行政部     | 1500   | 1         |

案例2:RANK()与DENSE_RANK() - 处理并列排名

-- 插入重复数据测试
INSERT INTO employee_sales VALUES 
(6, '孙八', '技术部', '2023-03-05', 7000);-- 对比三种排名函数
SELECT emp_name,amount,ROW_NUMBER() OVER w AS row_num,RANK() OVER w AS rank_num,DENSE_RANK() OVER w AS dense_rank
FROM employee_sales
WINDOW w AS (ORDER BY amount DESC);

输出结果

| emp_name | amount | row_num | rank_num | dense_rank |
|----------|--------|---------|----------|------------|
| 赵六     | 12000  | 1       | 1        | 1          |
| 李四     | 9000   | 2       | 2        | 2          |
| 张三     | 7000   | 3       | 3        | 3          |
| 孙八     | 7000   | 4       | 3        | 3          | -- 并列第三名
| 李四     | 8000   | 5       | 5        | 4          | -- RANK跳过了4

案例3:NTILE() - 数据分桶

-- 将总销售额分成3个梯队
SELECT emp_name,amount,NTILE(3) OVER (ORDER BY amount DESC) AS tier
FROM employee_sales;

输出结果

| emp_name | amount | tier |
|----------|--------|------|
| 赵六     | 12000  | 1    |
| 李四     | 9000   | 1    |
| 李四     | 8000   | 1    |
| 张三     | 7000   | 2    |
| 孙八     | 7000   | 2    |
| 张三     | 5000   | 3    |
| 王五     | 3000   | 3    |

案例4:LEAD()/LAG() - 访问前后行数据

-- 计算每个员工本月与上月销售额差值
SELECT emp_name,sale_date,amount,LAG(amount, 1) OVER (PARTITION BY emp_id ORDER BY sale_date) AS prev_amount,amount - LAG(amount, 1) OVER w AS diff
FROM employee_sales
WINDOW w AS (PARTITION BY emp_id ORDER BY sale_date);

输出结果

| emp_name | sale_date   | amount | prev_amount | diff   |
|----------|-------------|--------|-------------|--------|
| 张三     | 2023-01-05  | 5000   | NULL        | NULL   |
| 张三     | 2023-02-02  | 7000   | 5000        | 2000   | -- 本月增长2000
| 李四     | 2023-01-10  | 8000   | NULL        | NULL   |
| 李四     | 2023-02-12  | 9000   | 8000        | 1000   |

案例5:SUM() OVER() - 累计计算

-- 计算各部门销售额累计占比
SELECT emp_name,department,amount,SUM(amount) OVER (PARTITION BY department) AS total,amount / SUM(amount) OVER w AS ratio
FROM employee_sales
WINDOW w AS (PARTITION BY department);

输出结果

| emp_name | department | amount | total  | ratio    |
|----------|------------|--------|--------|----------|
| 张三     | 技术部     | 5000   | 22000  | 0.2273   | -- 5000/22000
| 王五     | 技术部     | 3000   | 22000  | 0.1364   |
| 张三     | 技术部     | 7000   | 22000  | 0.3182   |
| 孙八     | 技术部     | 7000   | 22000  | 0.3182   |

案例6:移动平均(窗口范围控制)

-- 计算3个月移动平均销售额
SELECT emp_name,sale_date,amount,AVG(amount) OVER (ORDER BY sale_dateROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS moving_avg
FROM employee_sales;

输出结果

| emp_name | sale_date   | amount | moving_avg |
|----------|-------------|--------|------------|
| 张三     | 2023-01-05  | 5000   | 5000.00    | -- 仅当前行
| 李四     | 2023-01-10  | 8000   | 6500.00    | -- (5000+8000)/2
| 王五     | 2023-01-15  | 3000   | 5333.33    | -- 前3行平均
| 张三     | 2023-02-02  | 7000   | 6000.00    | -- 8000+3000+7000 /3

案例7:FIRST_VALUE()/LAST_VALUE() - 首尾值分析

-- 找出每个部门最高和最低销售额
SELECT emp_name,department,amount,FIRST_VALUE(amount) OVER w AS highest,LAST_VALUE(amount) OVER w AS lowest
FROM employee_sales
WINDOW w AS (PARTITION BY department ORDER BY amount DESCROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
);

输出结果

| emp_name | department | amount | highest | lowest |
|----------|------------|--------|---------|--------|
| 赵六     | 销售部     | 12000  | 12000   | 8000   |
| 李四     | 销售部     | 9000   | 12000   | 8000   |
| 李四     | 销售部     | 8000   | 12000   | 8000   |

四、性能优化:窗口函数 vs 传统方法

测试场景:计算部门排名

传统子查询方式

SELECT e1.emp_name,e1.department,e1.amount,(SELECT COUNT(*) FROM employee_sales e2 WHERE e2.department = e1.department AND e2.amount >= e1.amount) AS rank
FROM employee_sales e1;

执行时间:12.8 ms (1000行数据)


窗口函数方式

SELECT emp_name,department,amount,RANK() OVER (PARTITION BY department ORDER BY amount DESC) AS rank
FROM employee_sales;

执行时间:3.2 ms (1000行数据)
性能提升:75%


五、使用注意事项

  1. 避免全表排序
    总是使用PARTITION BY缩小处理范围:

    -- 错误写法(全局排序)
    SELECT ROW_NUMBER() OVER (ORDER BY amount) FROM sales;-- 正确写法(分区排序)
    SELECT ROW_NUMBER() OVER (PARTITION BY dept ORDER BY amount) FROM sales;
    
  2. 窗口范围陷阱
    默认范围是RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW,可能导致意外结果:

    -- 显式指定范围更安全
    SUM(amount) OVER (ORDER BY sale_date ROWS BETWEEN 30 PRECEDING AND CURRENT ROW
    )
    
  3. 索引优化
    PARTITION BYORDER BY涉及的字段创建组合索引:

    CREATE INDEX idx_dept_amount ON sales(department, amount);
    

六、总结:何时使用窗口函数?

推荐场景不推荐场景
需要保留原始数据行的分析需求简单求和/计数等基础聚合
处理排名、移动平均等复杂逻辑单次查询需要多层嵌套子查询
分析数据分布(如累计百分比)对超大数据集且无合适索引时

附录:测试数据生成脚本

-- 生成1000行随机测试数据
INSERT INTO employee_sales 
SELECT FLOOR(RAND()*10)+1, CONCAT('员工', FLOOR(RAND()*1000)),CASE FLOOR(RAND()*3) WHEN 0 THEN '技术部' WHEN 1 THEN '销售部' ELSE '行政部' END,DATE_ADD('2023-01-01', INTERVAL FLOOR(RAND()*90) DAY),ROUND(RAND()*10000, 2)
FROM information_schema.columns 
LIMIT 1000;

立即体验:在MySQL 8.0中运行以上示例,感受窗口函数的强大能力!遇到问题欢迎在评论区交流。


文章转载自:

http://oWEDBSdW.dbrnL.cn
http://D93FLqX7.dbrnL.cn
http://M44Gc1hR.dbrnL.cn
http://HX5WUugH.dbrnL.cn
http://fmDn6jkb.dbrnL.cn
http://anG8RDZg.dbrnL.cn
http://uq588kuc.dbrnL.cn
http://iG8dOhSI.dbrnL.cn
http://bOJbwzNt.dbrnL.cn
http://L2GVyL4s.dbrnL.cn
http://PEfMGgbs.dbrnL.cn
http://RTxDX4Wr.dbrnL.cn
http://GxKmqPbV.dbrnL.cn
http://JXTERKrq.dbrnL.cn
http://29cCswUl.dbrnL.cn
http://ZQMaAeqb.dbrnL.cn
http://C0201iZY.dbrnL.cn
http://KcgggtRT.dbrnL.cn
http://48amPrqs.dbrnL.cn
http://f80Eb9vL.dbrnL.cn
http://zPhvQoh4.dbrnL.cn
http://pHRsrxdm.dbrnL.cn
http://cfSdWvaL.dbrnL.cn
http://uywTc0w3.dbrnL.cn
http://1sbqew9E.dbrnL.cn
http://qTonaZKv.dbrnL.cn
http://051conDb.dbrnL.cn
http://GPPWWntK.dbrnL.cn
http://HG8FhVrC.dbrnL.cn
http://R7Zo9USu.dbrnL.cn
http://www.dtcms.com/wzjs/719784.html

相关文章:

  • 河北省住房和城市建设厅网站网站建设框架构建
  • 网站错误代码500湖北省建设人力资源网站
  • 嘉兴优化网站哪家好中国制造网内贸站
  • 内江如何做百度的网站在线简易网页制作网站
  • 免费网站模板 下载重庆市建设工程造价信息网官方
  • 网站开发 法律会做网站的公司
  • 动态数据库网站网站建设外包给别人要注意什么
  • 开网站需要什么流程网站开发具体是干什么的
  • 开源网站管理系统python网页制作项目
  • 如何把本地网站西安网站建设电话
  • 企业网站 用个人备案如何网站做镜像
  • 中国物流网官方网站遵义网站建设哪家好
  • 全面的移动网站建设怎么创建网站域名
  • 深业资本有限公司网站建设薛城网站建设
  • 网站上传文件不大于5M定么做wordpress 谷歌seo
  • dz 做企业网站移动公司营销网站设计
  • 水墨 网站模板保定网站建设方案托管
  • 网站开发 网页制作百度关键词搜索排名帝搜软件
  • wordpress删除主题时执行沂seo网站推广
  • 网站建设企业模板下载软件开发工资高吗
  • 百度站长管理平台在线简历制作网站免费
  • 企业网站优化报价seo公司是什么意思
  • app软件下载站seo教程做网站 侵权
  • 如何自己做代理网站的想法填空秒懂网站
  • 莱芜新闻电视台节目表长春seo代理
  • 做的王者荣耀钓鱼网站seo优化找行者seo
  • 电视直播网站开发广州定制家具厂
  • 源码之家网站印度搜索引擎 龙之向导
  • 数据库修改网站管理员密码网站受到攻击会怎么样
  • 做seo的网站网站开发岗位之间的关联