You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL实现D&D加权概率批量战利品掉落的技术咨询

解决D&D战利品加权批量随机掉落的SQL方案

方法1:递归循环执行单条加权查询

直接复用你现有的单条LIMIT 1查询逻辑,通过递归生成指定次数的查询并合并结果,完全保留原有的加权概率,不受稀有度表行数限制。

示例代码(适配PostgreSQL/MySQL 8.0+):

WITH RECURSIVE generate_nums(n) AS (
    SELECT 1
    UNION ALL
    SELECT n + 1 FROM generate_nums WHERE n < 10 -- 替换成你需要的战利品数量
)
SELECT loot.*
FROM generate_nums
CROSS JOIN LATERAL (
    -- 这里替换成你原来的单条加权随机查询
    SELECT loot.*
    FROM loot
    JOIN rarity ON loot.rarity_id = rarity.id
    ORDER BY RAND() * rarity.weight DESC
    LIMIT 1
) AS loot;
  • 优势:逻辑简单,直接复用已有代码,概率完全匹配你的权重设置。
  • 适用场景:批量数量不大(比如10-50个),开发成本低。

方法2:累积权重批量匹配(更高效)

通过计算稀有度的累积权重区间,一次性生成所有随机数并匹配对应的稀有度,再从对应稀有度的战利品中随机选取,性能比多次查询更优,适合批量生成大量战利品。

示例代码:

-- 生成指定数量的随机值
WITH random_values AS (
    SELECT
        RAND() * (SELECT SUM(weight) FROM rarity) AS rand_val,
        ROW_NUMBER() OVER () AS rn
    FROM generate_series(1, 10) -- PostgreSQL用此生成序列;MySQL替换为递归CTE生成数字
),
-- 计算每个稀有度的权重区间
rarity_ranges AS (
    SELECT
        id,
        weight,
        SUM(weight) OVER (ORDER BY id) AS upper_bound,
        SUM(weight) OVER (ORDER BY id) - weight AS lower_bound
    FROM rarity
),
-- 匹配随机值到对应的稀有度
matched_rarities AS (
    SELECT
        rv.rn,
        rr.id AS rarity_id
    FROM random_values rv
    JOIN rarity_ranges rr ON rv.rand_val BETWEEN rr.lower_bound AND rr.upper_bound
)
-- 从匹配的稀有度中随机选战利品
SELECT l.*
FROM matched_rarities mr
JOIN loot l ON l.rarity_id = mr.rarity_id
ORDER BY mr.rn, RAND();
  • 优势:只生成一次随机数,查询效率更高,适合批量生成几十上百个战利品。
  • 注意:MySQL没有generate_series,可以用方法1中的generate_nums递归CTE替换生成随机值的部分。

额外提示

  • 可以多运行几次查询,统计各稀有度的出现次数,验证是否符合权重比例(比如weight=50的稀有度出现次数应该是weight=10的5倍左右)。
  • 如果你的战利品表中同一稀有度有多个物品,上述方法会随机选取该稀有度下的任意物品,完全符合D&D的随机掉落逻辑。

内容的提问来源于stack exchange,提问作者montalope

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 19:45:38