SQL80 打折

在示例商店的打折活动中,所有产品降价10%。使用SQL语句从Products表中检索prod_id、prod_price,并计算出sale_price(即原价的90%)。查询结果展示了产品ID、原价格和促销价格。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

描述

我们的示例商店正在进行打折促销,所有产品均降价 10%。Products表包含prod_id产品id、prod_price产品价格

【问题】编写 SQL语句,从 Products 表中返回 prod_id、prod_price 和 sale_price。sale_price 是一个包含促销价格的计算字段。提示:可以乘以 0.9,得到原价的 90%(即 10%的折扣)

【示例结果】

返回产品id prod_id、产品价格prod_price、销售价格 sale_price

prod_id

prod_price

sale_price

a0011

9.49

8.541

a0019

600

540

b0019

1000

900

【示例解析】sale_price的价格是prod_price的90%

示例1

输入:

DROP TABLE IF EXISTS `Products`;

CREATE TABLE IF NOT EXISTS `Products` (

`prod_id` VARCHAR(255) NOT NULL COMMENT '产品 ID',

`prod_price` DOUBLE NOT NULL COMMENT '产品价格'

);

INSERT INTO `Products` VALUES ('a0011',9.49),

('a0019',600),

('b0019',1000);

复制

输出:

prod_id|prod_price|sale_price

a0011|9.490|8.541

a0019|600.000|540.000

b0019|1000.000|900.000

答案

select prod_id,prod_price,prod_price*0.9 as sale_price  --要注意题目中写了,只有prod_id和prod_price这2个字段,sale_price是prod_price打了九折之后的价格
from Products
### 商品打折天数计算的 SQL 面试题 #### 问题描述 给定一张 `sales_data` 表,其中包含商品的销售记录以及折扣信息。表结构如下: | 字段名 | 类型 | 描述 | |----------------|----------|--------------------| | product_id | INT | 商品 ID | | sale_date | DATE | 销售日期 | | discount_rate | FLOAT | 折扣率(0~1之间) | 目标是编写一段 SQL 查询,统计每个商品连续打折的最长天数。 --- #### 解决方案 为了实现这一需求,可以采用窗口函数配合自定义变量的方式完成。以下是详细的解决方法及其解析。 ##### 数据预处理 首先通过窗口函数为每一行分配一个唯一的编号,并基于商品 ID 和时间顺序进行分区排序。这一步骤可以通过 `ROW_NUMBER()` 实现[^3]。 ```sql SELECT product_id, sale_date, discount_rate, ROW_NUMBER() OVER (PARTITION BY product_id ORDER BY sale_date) AS rn FROM sales_data; ``` 此部分的作用是对同一商品按照时间先后顺序排列并赋予唯一序号。 --- ##### 连续性判断 对于连续性的判断,通常会引入辅助列来标记断点位置。这里的关键在于比较当前行与上一行的时间间隔是否满足特定条件(如一天)。如果满足,则认为属于同一次连续事件;否则视为新事件起点。 具体做法是在上述基础上增加两步操作: 1. **使用 LAG 函数获取前一日的数据**。 2. **计算日期差值并与折扣状态结合判定连贯性**。 代码片段如下所示: ```sql WITH RankedSales AS ( SELECT product_id, sale_date, discount_rate, ROW_NUMBER() OVER (PARTITION BY product_id ORDER BY sale_date) AS rn, CASE WHEN LAG(discount_rate, 1) OVER (PARTITION BY product_id ORDER BY sale_date) IS NULL OR ABS(DATEDIFF(sale_date, LAG(sale_date, 1) OVER (PARTITION BY product_id ORDER BY sale_date))) != 1 THEN 1 ELSE 0 END AS is_new_group_flag FROM sales_data ) ``` 此处新增了一个布尔标志位 `is_new_group_flag` 来指示是否存在新的分组情况发生[^4]。 --- ##### 聚合计算 最后一步则是依据前面构建好的逻辑框架执行聚合运算得出最终结果。核心思想是以累计求和的形式动态更新所属组别索引,从而便于后续按需汇总统计数据。 完整脚本展示如下: ```sql WITH GroupedSales AS ( WITH RankedSales AS ( SELECT product_id, sale_date, discount_rate, ROW_NUMBER() OVER (PARTITION BY product_id ORDER BY sale_date) AS rn, SUM(CASE WHEN LAG(discount_rate, 1) OVER (PARTITION BY product_id ORDER BY sale_date) IS NULL OR ABS(DATEDIFF(sale_date, LAG(sale_date, 1) OVER (PARTITION BY product_id ORDER BY sale_date))) != 1 THEN 1 ELSE 0 END) OVER (ORDER BY product_id, sale_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS group_idx FROM sales_data WHERE discount_rate < 1 -- 只考虑有折扣的情况 ) SELECT product_id, MIN(sale_date) AS start_date, MAX(sale_date) AS end_date, COUNT(*) AS consecutive_days_count FROM RankedSales GROUP BY product_id, group_idx ), FinalResult AS ( SELECT product_id, MAX(consecutive_days_count) AS max_consecutive_discount_days FROM GroupedSales GROUP BY product_id ) SELECT * FROM FinalResult; ``` 以上查询实现了逐层拆解复杂业务场景的目标,既兼顾性能又保持可读性强的特点[^1]。 --- ### 总结 该案例展示了如何运用高级 SQL 特性(如窗口函数、CTE 等),针对实际应用场景设计高效解决方案的过程。通过对原始数据逐步加工提炼直至获得所需指标,充分体现了 SQL 编程的强大能力。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值