5,891
社区成员




最近在学sql,碰上一个问题,就是我有张表spzl,里面有这个商品活动时间,每组可销售的最大值和最小值,活动要求的总数量,现在需要把这个总数量随机分配到活动时间内,该怎么写比较好呢?
例如:1.a商品活动时间为3月1日-3月7日共7天,活动要求的总数量是300,现需要把300的数量随机分到7天中
2.然后再通过可销售的最大值4,最小值2计算出每天最多能销售几组,剩下不能整除的零头做一组
总数量 | 300 | 时间 | 3-1 | 3-7 | 活动天数 | 7 | |
天数 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
随机分摊数量 | 36 | 41 | 48 | 45 | 34 | 36 | 60 |
最大销售组数 | 18 | 20+1 | 24 | 22+1 | 17 | 18 | 30 |
最小销售组数 | 9 | 10+1 | 12 | 11+1 | 8+1 | 9 | 15 |
CREATE TABLE spzl (
id INT PRIMARY KEY,
start_date DATE,
end_date DATE,
total_amount INT,
max_sellable INT,
min_sellable INT,
days INT,
random_amounts VARCHAR(50),
max_sellable_counts VARCHAR(50),
min_sellable_counts VARCHAR(50)
);
其中,各个字段的含义如下:
id:商品的唯一标识,可以使用自增的整数。
start_date:商品活动的开始日期,使用 DATE 类型存储。
end_date:商品活动的结束日期,使用 DATE 类型存储。
total_amount:商品活动的总数量。
max_sellable:每组商品可销售的最大数量。
min_sellable:每组商品可销售的最小数量。
days:商品活动的天数,可以通过计算 start_date 和 end_date 之间的天数得到。
random_amounts:将商品活动总数量随机分配到每天的数量,使用 VARCHAR 类型存储,例如 "36,41,48,45,34,36,60"。
max_sellable_counts:每天最多能销售的组数,使用 VARCHAR 类型存储,例如 "18,20+1,24,22+1,17,18,30"。
min_sellable_counts:每天最少能销售的组数,使用 VARCHAR 类型存储,例如 "9,10+1,12,11+1,8+1,9,15"。
-- 计算商品活动时间的天数
UPDATE spzl SET days = DATEDIFF(end_date, start_date) + 1;
-- 计算每天的随机分配数量
UPDATE spzl
SET daily_quantity = FLOOR(quantity / days),
remaining_quantity = quantity - FLOOR(quantity / days) * days;
-- 随机分配每天的数量
INSERT INTO spzl_random (id, date, quantity)
SELECT id,
DATE_ADD(start_date, INTERVAL seq DAY) AS date,
IF(seq < remaining_quantity, daily_quantity + 1, daily_quantity) AS quantity
FROM spzl
JOIN (SELECT 0 AS seq UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3
UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7) AS seq
ON seq < days;
-- 计算每天最多和最少能销售的商品组数
SELECT date,
CEIL(quantity / max_sale) AS max_sale_num,
FLOOR(quantity / min_sale) AS min_sale_num
FROM (
SELECT date,
SUM(quantity) AS quantity,
MAX(max_sale_quantity) AS max_sale,
MIN(min_sale_quantity) AS min_sale
FROM (
SELECT date,
SUM(quantity) AS quantity,
MAX(daily_quantity) AS max_sale_quantity,
MIN(daily_quantity) AS min_sale_quantity
FROM spzl_random
GROUP BY date
) AS t1
JOIN spzl ON t1.id = spzl.id
GROUP BY date
) AS t2;
第一个 UPDATE 语句计算商品活动时间的天数,并将其存储在 spzl 表中的一个名为 days 的新列中。
第二个 UPDATE 语句根据总数量和天数计算出每天的随机分配数量,并将其存储在 spzl 表中的一个名为 daily_quantity 的新列中。同时,它还计算出剩余数量 remaining_quantity。
INSERT INTO 语句将每天的随机分配数量存储在一个名为 spzl_random 的新表中,其中使用了 IF 函数来处理剩余数量
condition 是一个逻辑表达式或值,如果为 TRUE,则返回 value_if_true,否则返回 value_if_false。
value_if_true 是当 condition 为 TRUE 时返回的值。
value_if_false 是当 condition 为 FALSE 时返回的值。
在上面的 SQL 语句中,condition 就是 seq < remaining_quantity,即当前日期的序号是否小于剩余数量;value_if_true 是 daily_quantity + 1,即如果当前日期的序号小于剩余数量,则返回 daily_quantity + 1;value_if_false 是 daily_quantity,即如果当前日期的序号大于等于剩余数量,则返回 daily_quantity。