提问人:Mike Smith 提问时间:7/22/2023 最后编辑:LuukMike Smith 更新时间:7/24/2023 访问量:35
在单词定义的 MYSQL 表中,在 sql 中添加从其他行随机获取的 3 列/定义字段
In a MYSQL table of word definitions, within sql add 3 columns/fields of definitions taken randomly from other rows
问:
我有一个名为 aa_ngl_defs 的 MYSQL 表,形式如下:
编号 | 词 | POS机 | 定义 |
---|---|---|---|
1 | 这 | 品 | 用于指向已经提到的内容 |
2 | 是 | 动词 | 用于显示事物的身份 |
3 | 和 | 康杰 | 用于连接单词或单词组 |
4 | 之 | 准备 | 属于某物或与某物有关 |
5 | 自 | 准备 | 用于指示地点或方向 |
6 | 一个 | 品 | 一个特定的事物或一类事物中的一个 |
7 | 在 | 准备 | 用于表示处于其他事物内部或被其他事物包围 |
8 | 有 | 动词 | 拥有、拥有或持有某物 |
9 | 它 | 代词 | 前面已经提到过的事情 |
10 | 你 | 代词 | 用于指代说话者正在讲话的人 |
11 | 他 | 代词 | 用于指代作为主语的男性 |
12 | 为 | 准备 | 表明某事的目的或需要 |
13 | 他们 | 代词 | 用于指代两个或两个以上的人、动物或事物 |
14 | 不 | 副词 | 用于使表达式为负数 |
15 | 那 | 调整 | 用于识别特定的人、事物、事实或想法 |
16 | 我们 | 代词 | 用于指代说话者和另一个人作为主语 |
17 | 上 | 准备 | 触摸和被某物支撑或身体接触 |
该表在 id 列中具有唯一的连续整数。
我想通过添加从此表中的其他行随机获取的 3 列定义来创建一个新表。这将允许我创建具有 3 个干扰项的测验。我需要合理的性能速度,但不一定是高速,因为表格有 3,500 行,但我只需要每周生成一次新测验。
所以它看起来像这样:
id Word POS Correct_Definition Distractor1 Distractor2 Distractor3
在线测验生成器 Quizlet、Kahoot 和 Blooket 能够获取这样的简单列表,并生成具有 3 个干扰项的测验。这就是我试图效仿的。
以下方法可用于添加 1 个额外的干扰项定义:
SELECT t1.id, t1.Word, t1.Definition, t2.Definition
FROM aa_ngl_defs AS t1
LEFT JOIN aa_ngl_defs AS t2
ON t1.id <> t2.id -- Ensure we don't join the row with itself
ORDER BY RAND()
LIMIT 3;
但是我不知道如何再添加两个干扰项定义,而且我的查询花了 17 秒,我怀疑如果我尝试添加更多列,它会成倍增加。
我尝试结合以下内容来提高性能
SELECT *
FROM aa_ngl_defs AS r1 JOIN
(SELECT (RAND() * (SELECT MAX(id) FROM aa_ngl_defs)) AS id
)
AS r2
WHERE r1.id >= r2.id
ORDER BY r1.id ASC
LIMIT 1;
...这可以非常快速地随机选择一行,但我完全不知道如何合并它来添加三个干扰项。我想我需要嵌套的选择语句或变量。
显然,由于每行将有 3 个干扰项,因此各行之间会有一些重复的干扰项,但我在任何一行中都不能有重复的干扰项。随机性只需要合理地随机,而不是严格意义上的随机性。
答:
看看这是否适合你。可以将随机行逻辑移动到横向联接中,然后应用row_number,然后应用条件聚合以透视到所需的列:
select id, word, pos, Definition Correct_Definition,
max(case when cn = 1 then rdef end) Distractor1,
max(case when cn = 2 then rdef end) Distractor2,
max(case when cn = 3 then rdef end) Distractor3
from (
select *, row_number() over(partition by t.id) cn
from t
join lateral (
select definition rdef
from t t2
where t2.id != t.id
order by rand()
limit 3
)r
)t
group by id, word, pos, definition;
观看此演示 Fiddle
评论
创建一个名为 的临时表。填写并按 订购。这是最慢的步骤,不会很慢。(包括一个索引以帮助步骤 3。
distractors
definition
RAND()
distractor
用今天的 17 个随机问题创建表格(还没有干扰项)。这可能涉及.请务必包含 ids 1..17,如示例中所示。
quiz
ORDER BY RAND() LIMIT 17
从今天的 17 个问题中删除。(多表)(这样可以避免与结果中的任何问题匹配的任何干扰项)
distractors
DELETE
ALTER TABLE distractors ADD id INT AUTO_INCREMENT PRIMARY KEY;
(这将创建要在下一步中使用的数字。将第一个随机的 17 个问题从 中添加到 。将接下来的 17 个问题添加到 ;等。使用类似这样的东西来执行此步骤。(这样可以防止任何重复的干扰器。
distractors
quiz.distractor1
distractor2
UPDATE quiz JOIN distractors ON distractors.id = quiz.id + 0; SET quiz.distractor1 = distractors.definition UPDATE quiz JOIN distractors ON distractors.id = quiz.id + 17; SET quiz.distractor2 = distractors.definition UPDATE quiz JOIN distractors ON distractors.id = quiz.id + 34; SET quiz.distractor3 = distractors.definition
(这 3 个仅在两个地方有所不同。UPDATEs
提示:使用 ,而不是 -- 这样索引就可以工作了。(可能没有任何长定义。VARCHAR(191)
TEXT
评论