SQL-DAY 8(SQL窗口函数的应用案例:电商平台订单信息案例分析)


一、窗口函数说明

1.窗口函数的语句结构

  • 窗口函数的语法格式
函数名 ([expr]) over(子句)

函数名 ([expr]) over( partition by <要分列的组> order by <要排序的列> rows between <数据范围>)

其中over关键字后子句包含三个分析子句
 分组子句partition by
 排序子句order by
 窗口子句rows

sum A over (partition by B order by C rows between D1 and D2)
avg A over(partition by B order by C rows between D1 and D2)
  • rows子句的相关示例
rows between 2 preceding and current row # 取当前行和前面两行

rows between unbounded preceding and current row # 包括本行和之前所有的行

rows between current row and unbounded following # 包括本行和之后所有的行

rows between 3 preceding and 1 following # 取前面三行和下面一行,包含当前行,总共五行

注意:
  当order by后面缺少窗口从句条件,窗口规范默认是rows between unbounded preceding and current row.
  当order by和窗口从句都缺失, 窗口规范默认是 rows between unbounded preceding and unbounded following

2.窗口函数的分类

  • 窗口函数分为两种
专用窗口函数 聚合类窗口函数
rank() 并列排名会跳号 sum()
dense_rank() 并列排名不会跳号 count()
row_number() 生成行的编号 avg()
max()
min()

二、案例分析(电商平台订单信息)

1.数据准备

表结构

列名 释义
user_name 用户名
piece 购买数量
price 价格
pay_amount 支付金额
goods_category 商品品类
pay_time 支付日期

建表语句

use lagou;
create table user_trade (
	user_name varchar(20),
	piece int,
	price double,
	pay_amount double,
	goods_category varchar(20),
	pay_time date
);

2.窗口函数之累计计算函数

需求1: 查询出2019年每月的支付总额和当年累积支付总额

-- step1 过滤出2019年数据
select * from user_trade where year(pay_time)=2019;

-- st
项目一Spark离线处理本项目来源于企业级电商网站的大数据统计分析平台,该平台以 Spark 框架为核心,对电商网站的日志进行离线和实时分析。 该大数据分析平台对电商网站的各种用户行为(访问行为、购物行为、广告点击行为等)进行分析,根据平台统计出来的数据,辅助公司中的 PM(产品经理)、数据分析师以及管理人员分析现有产品的情况,并根据用户行为分析结果持续改进产品的设计,以及调整公司的战略和业务。最终达到用大数据技术来帮助提升公司的业绩、营业额以及市场占有率的目标。 本项目使用了 Spark 技术生态栈中最常用的三个技术框架,Spark Core、Spark SQL 和 Spark Streaming,进行离线计算和实时计算业务模块的开发。实现了包括用户访问 session 分析、页面单跳转化率统计、热门商品离线统计、广告流量实时统计 4 个业务模块。通过合理的将实际业务模块进行技术整合与改造,该项目几乎完全涵盖了 Spark Core、Spark SQL 和 Spark Streaming 这三个技术框架中大部分的功能点、知识点,学员对于 Spark 技术框架的理解将会在本项目中得到很大的提高。 项目二Spark实时处理项目简介对于实时性要求高的应用,如用户即时详单查询,业务量监控等,需要应用实时处理架构项目场景对于实时要求高的应用、有对数据进行实时展示和查询需求时项目技术分别使用canal和kafka搭建各自针对业务数据库和用户行为数据的实时数据采集系统,使用SparkStreaming搭建高吞吐的数据实时处理模块,选用ES作为最终的实时数据处理结果的存储位置,并从中获取数据进行展示,进一步降低响应时间。 
<think>好的,用户之前让我介绍了MySQL的索引知识点,现在他们又提出了一个新的请求:“请使用中文回答我或者给我介绍一下: 请使用电商sql”。我需要分析用户的需求到底是什么。 首先,用户提到“使用电商sql”,可能是在询问如何设计一个电商平台数据库结构,或者需要示例的SQL语句来展示电商相关的查询。考虑到之前提供的索引知识,用户可能希望看到实际的SQL应用案例,特别是在电商场景下如何应用这些索引优化。 接下来,我需要考虑用户可能的身份。他们可能是开发人员、数据库管理员,或者正在学习数据库的学生。如果是开发人员,可能需要实际的表结构和查询示例;如果是学生,可能需要更基础的建表语句和常见查询示例。 用户的需求可能包括电商数据库的核心表设计(比如用户表、商品表、订单表等)、常见的SQL查询(如查询订单详情、统计销售额)、以及如何优化这些查询的索引策略。此外,还可能涉及事务处理,比如下单过程中的库存扣减,确保数据的一致性。 需要注意的是,用户之前已经接触过索引的知识,因此在示例中可能需要融入索引的使用建议,展示如何在实际场景中应用这些知识。例如,在订单表中为user_id和product_id创建索引,优化查询性能。 另外,用户可能没有明确说明是否需要具体的SQL代码,但根据之前的回答风格,提供结构化的示例会更符合他们的预期。可能需要包括DDL(数据定义语言)和DML(数据操作语言)的示例,以及事务处理的示例。 最后,要确保回答清晰、结构化,分点说明,可能包括表结构设计、示例数据插入、常见查询、事务处理以及索引优化建议。这样用户能够全面了解电商SQL应用,同时巩固之前学习的索引知识。</think>以下是电商场景核心SQL设计与典型查询示例(包含表结构、业务逻辑及索引优化): --- ### 一、基础表结构设计(DDL) ```sql /* 用户表:存储注册用户信息 */ CREATE TABLE users ( user_id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY COMMENT '用户ID', username VARCHAR(50) NOT NULL UNIQUE COMMENT '登录账号', password_hash CHAR(60) NOT NULL COMMENT '加密密码', mobile CHAR(11) NOT NULL COMMENT '手机号', create_time DATETIME DEFAULT CURRENT_TIMESTAMP, INDEX idx_mobile (mobile) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; /* 商品表:商品基本信息 */ CREATE TABLE products ( product_id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, product_name VARCHAR(200) NOT NULL COMMENT '商品名称', category_id INT NOT NULL COMMENT '类目ID', price DECIMAL(10,2) UNSIGNED NOT NULL COMMENT '销售价', stock INT UNSIGNED NOT NULL COMMENT '库存', is_on_sale BOOLEAN DEFAULT 0 COMMENT '上架状态', FULLTEXT INDEX ft_product_name (product_name) WITH PARSER ngram ) ENGINE=InnoDB; /* 订单主表:订单概要 */ CREATE TABLE orders ( order_id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, user_id INT UNSIGNED NOT NULL, total_amount DECIMAL(12,2) UNSIGNED NOT NULL COMMENT '订单总额', status TINYINT NOT NULL COMMENT '1待支付 2已发货 3已完成', create_time DATETIME DEFAULT CURRENT_TIMESTAMP, INDEX idx_user_status (user_id, status), FOREIGN KEY (user_id) REFERENCES users(user_id) ); /* 订单明细表:商品购买明细 */ CREATE TABLE order_items ( item_id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, order_id BIGINT UNSIGNED NOT NULL, product_id INT UNSIGNED NOT NULL, quantity SMALLINT UNSIGNED NOT NULL COMMENT '购买数量', price DECIMAL(10,2) UNSIGNED NOT NULL COMMENT '成交单价', INDEX idx_order_product (order_id, product_id), FOREIGN KEY (order_id) REFERENCES orders(order_id), FOREIGN KEY (product_id) REFERENCES products(product_id) ); ``` --- ### 二、典型业务SQL示例 #### 1. 用户行为分析 ```sql -- 查询最近7天消费TOP10用户 SELECT u.user_id, u.username, SUM(o.total_amount) AS total_spent FROM users u JOIN orders o ON u.user_id = o.user_id WHERE o.create_time >= DATE_SUB(NOW(), INTERVAL 7 DAY) GROUP BY u.user_id ORDER BY total_spent DESC LIMIT 10; -- 使用覆盖索引优化:在orders表添加(user_id, create_time, total_amount)复合索引 ``` #### 2. 商品库存管理 ```sql -- 带事务的库存扣减(防止超卖) START TRANSACTION; UPDATE products SET stock = stock - 3 WHERE product_id = 1001 AND stock >= 3; INSERT INTO order_items(order_id, product_id, quantity, price) VALUES (20001, 1001, 3, (SELECT price FROM products WHERE product_id=1001)); COMMIT; ``` #### 3. 订单分页查询 ```sql -- 获取用户最近订单(按时间倒序分页) SELECT o.order_id, o.total_amount, o.status, GROUP_CONCAT(p.product_name SEPARATOR ', ') AS products FROM orders o JOIN order_items i ON o.order_id = i.order_id JOIN products p ON i.product_id = p.product_id WHERE o.user_id = 12345 GROUP BY o.order_id ORDER BY o.create_time DESC LIMIT 0, 10; -- 优化方案:在orders.user_id字段加索引,使用延迟关联 ``` --- ### 三、高级查询技巧 #### 1. 类目销售统计(窗口函数) ```sql SELECT category_id, SUM(quantity) OVER (PARTITION BY category_id) AS category_total, RANK() OVER (ORDER BY SUM(quantity) DESC) AS sales_rank FROM order_items i JOIN products p ON i.product_id = p.product_id WHERE i.create_time BETWEEN '2023-01-01' AND '2023-12-31'; ``` #### 2. 商品关联推荐(自连接) ```sql -- 查找常被同时购买的商品 SELECT a.product_id AS prod1, b.product_id AS prod2, COUNT(*) AS purchase_count FROM order_items a JOIN order_items b ON a.order_id = b.order_id AND a.product_id < b.product_id GROUP BY prod1, prod2 HAVING purchase_count > 10 ORDER BY purchase_count DESC; ``` --- ### 四、性能优化建议 1. **索引策略**: - 订单表`orders`:联合索引`(user_id, create_time)` - 商品表`products`:`category_id`索引 + 价格区间索引 - 订单明细`order_items`:`(product_id, create_time)`用于商品销售分析 2. **分区方案**: ```sql ALTER TABLE orders PARTITION BY RANGE (YEAR(create_time)) ( PARTITION p2022 VALUES LESS THAN (2023), PARTITION p2023 VALUES LESS THAN (2024) ); ``` 3. **缓存策略**: ```sql -- 使用查询缓存(适合读多写少场景) SELECT SQL_CACHE product_name, price FROM products WHERE product_id = 1001; ```
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值