Files
mp-java/src/main/resources/sql/coupon_status_optimization.sql
赵忠林 b2e0aa9f28 feat(优惠券): 实现优惠券状态管理功能
- 新增优惠券状态管理相关实体类字段和方法
- 实现优惠券状态自动更新和手动更新功能- 添加优惠券适用范围验证逻辑
- 新增优惠券状态查询和统计接口
- 优化数据库索引和查询性能
2025-08-15 00:35:55 +08:00

195 lines
5.7 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- 优惠券状态管理优化SQL脚本
-- 作者: WebSoft
-- 日期: 2025-01-15
-- 说明: 优化优惠券查询性能,添加必要的索引
-- ========================================
-- 1. 添加索引优化查询性能
-- ========================================
-- 用户优惠券表索引优化
CREATE INDEX IF NOT EXISTS idx_user_coupon_status ON shop_user_coupon(user_id, status, expire_time);
CREATE INDEX IF NOT EXISTS idx_user_coupon_expire ON shop_user_coupon(expire_time) WHERE status = 0;
CREATE INDEX IF NOT EXISTS idx_user_coupon_order ON shop_user_coupon(order_id) WHERE status = 1;
-- 优惠券模板表索引优化
CREATE INDEX IF NOT EXISTS idx_coupon_status_expire ON shop_coupon(status, expire_type, end_time);
-- ========================================
-- 2. 统一状态字段(如果需要数据迁移)
-- ========================================
-- 检查现有数据的状态一致性
SELECT
'状态一致性检查' as check_item,
COUNT(*) as total_count,
SUM(CASE WHEN status = 0 AND is_use = 0 AND is_expire = 0 THEN 1 ELSE 0 END) as available_count,
SUM(CASE WHEN status = 1 AND is_use = 1 THEN 1 ELSE 0 END) as used_count,
SUM(CASE WHEN status = 2 OR is_expire = 1 THEN 1 ELSE 0 END) as expired_count,
SUM(CASE WHEN
(status = 0 AND (is_use = 1 OR is_expire = 1)) OR
(status = 1 AND is_use = 0) OR
(status = 2 AND is_expire = 0)
THEN 1 ELSE 0 END) as inconsistent_count
FROM shop_user_coupon;
-- 修复状态不一致的数据
UPDATE shop_user_coupon
SET status = 1, is_use = 1
WHERE status = 0 AND is_use = 1 AND is_expire = 0;
UPDATE shop_user_coupon
SET status = 2, is_expire = 1
WHERE status = 0 AND is_expire = 1;
UPDATE shop_user_coupon
SET status = 2, is_expire = 1
WHERE status IN (0, 1) AND end_time < NOW();
-- ========================================
-- 3. 添加触发器自动更新过期状态(可选)
-- ========================================
DELIMITER $$
-- 创建触发器:在查询时自动检查过期状态
CREATE TRIGGER IF NOT EXISTS tr_check_coupon_expire
BEFORE UPDATE ON shop_user_coupon
FOR EACH ROW
BEGIN
-- 如果是未使用状态且已过期,自动更新为过期状态
IF NEW.status = 0 AND NEW.end_time < NOW() THEN
SET NEW.status = 2;
SET NEW.is_expire = 1;
END IF;
END$$
DELIMITER ;
-- ========================================
-- 4. 创建视图简化查询
-- ========================================
-- 创建用户可用优惠券视图
CREATE OR REPLACE VIEW v_user_available_coupons AS
SELECT
uc.*,
c.name as coupon_name,
c.description as coupon_description,
c.apply_range,
c.apply_range_config,
CASE
WHEN uc.end_time < NOW() THEN '已过期'
WHEN uc.status = 1 THEN '已使用'
WHEN uc.status = 0 THEN '可使用'
ELSE '未知状态'
END as status_desc
FROM shop_user_coupon uc
LEFT JOIN shop_coupon c ON uc.coupon_id = c.id
WHERE uc.deleted = 0;
-- 创建优惠券统计视图
CREATE OR REPLACE VIEW v_coupon_statistics AS
SELECT
user_id,
COUNT(*) as total_count,
SUM(CASE WHEN status = 0 AND end_time >= NOW() THEN 1 ELSE 0 END) as available_count,
SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) as used_count,
SUM(CASE WHEN status = 2 OR end_time < NOW() THEN 1 ELSE 0 END) as expired_count
FROM shop_user_coupon
WHERE deleted = 0
GROUP BY user_id;
-- ========================================
-- 5. 存储过程:批量处理过期优惠券
-- ========================================
DELIMITER $$
CREATE PROCEDURE IF NOT EXISTS sp_update_expired_coupons()
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE update_count INT DEFAULT 0;
-- 声明异常处理
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
RESIGNAL;
END;
START TRANSACTION;
-- 批量更新过期优惠券
UPDATE shop_user_coupon
SET status = 2, is_expire = 1
WHERE status = 0
AND end_time < NOW()
AND deleted = 0;
-- 获取更新数量
SET update_count = ROW_COUNT();
COMMIT;
-- 返回更新数量
SELECT update_count as updated_count;
END$$
DELIMITER ;
-- ========================================
-- 6. 性能监控查询
-- ========================================
-- 查看优惠券状态分布
SELECT
status,
CASE
WHEN status = 0 THEN '未使用'
WHEN status = 1 THEN '已使用'
WHEN status = 2 THEN '已过期'
ELSE '未知'
END as status_name,
COUNT(*) as count,
ROUND(COUNT(*) * 100.0 / (SELECT COUNT(*) FROM shop_user_coupon WHERE deleted = 0), 2) as percentage
FROM shop_user_coupon
WHERE deleted = 0
GROUP BY status
ORDER BY status;
-- 查看即将过期的优惠券7天内
SELECT
COUNT(*) as expiring_soon_count,
MIN(end_time) as earliest_expire_time,
MAX(end_time) as latest_expire_time
FROM shop_user_coupon
WHERE status = 0
AND end_time BETWEEN NOW() AND DATE_ADD(NOW(), INTERVAL 7 DAY)
AND deleted = 0;
-- 查看优惠券使用率统计
SELECT
DATE(create_time) as date,
COUNT(*) as issued_count,
SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) as used_count,
ROUND(SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) * 100.0 / COUNT(*), 2) as usage_rate
FROM shop_user_coupon
WHERE deleted = 0
AND create_time >= DATE_SUB(NOW(), INTERVAL 30 DAY)
GROUP BY DATE(create_time)
ORDER BY date DESC;
-- ========================================
-- 7. 清理和维护
-- ========================================
-- 清理过期很久的优惠券记录(可选,谨慎使用)
-- DELETE FROM shop_user_coupon
-- WHERE status = 2
-- AND end_time < DATE_SUB(NOW(), INTERVAL 1 YEAR)
-- AND deleted = 0;
COMMIT;