我正在尝试想出一种方法,将两个人从大约 6 人的更大数据集中分配到一起。我在玩弄 postgres 中的 random() 函数,但没有运气。我可以访问 postgres 或 oracle,以更容易完成此操作为准。 例如,如果我有 6 个名字,我想使用这 6 个名字并使用某种随机查询将它们分配给另一个:
- 比利
- 鲍勃
- 乔
- 山姆
- 约翰
- 亚历克斯
输出会是这样的:
原名|匹配
- 比利 |亚历克斯
- 鲍勃 |乔
- 乔 |约翰
- 山姆 |鲍勃
- 约翰 |比利
- 亚历克斯 |山姆
如有任何帮助,我们将不胜感激!
谢谢。
最佳答案
在 postgres 中,您可以在随机数上生成一个 row_number(),然后加入它。这很好而且很快,但它可能会导致人们与自己结为好友:
SELECT t1.name, t2.name
FROM (SELECT row_number() OVER (ORDER BY random()) as id, name FROM table) t1
INNER JOIN (SELECT row_number() OVER (order by random()) as id, name FROM table) t2
ON t1.id = t2.id;
这是一种使用笛卡尔积的方法,该积是将表连接到自身的结果。如果数据很大,这不是一个好的解决方案,因为有一个中间结果集是 (N * (N - 1)) 行,但没有人会与自己匹配:
SELECT name1,
name2
FROM (
SELECT t1.NAME name1,
t2.NAME name2,
row_number() OVER (PARTITION BY t1.NAME ORDER BY random()) AS rn
FROM yourtable t1,
yourtable t2
WHERE t1.NAME <> t2.NAME
) subquery
WHERE rn = 1;
这是两者的混合体。在一系列随机生成的 ID 上将表连接到自身,同时指定名称不匹配。中间结果集将从 t2
中为 t1
中的每个名称随机选择 1-3 个名称。然后我们随便拿一个。这有一个中间结果集,它总是少于 (N*3) 条记录,这还不错。
更新:但是,这将多次匹配同一个人...将它留在此处,以防它为 INNER JOIN 产生了阻止这种情况发生的好主意。
WITH randnames AS
(
SELECT row_number() OVER (ORDER BY random()) AS id,
NAME
FROM yourtable
)
SELECT name1, name2
FROM (
SELECT t1.NAME name1,
t2.NAME name2,
ROW_NUMBER() OVER (PARTITION BY t1.NAME ORDER BY 1) AS rn
FROM randnames t1
INNER JOIN randnames t2
ON t1.NAME <> t2.NAME
AND t2.id BETWEEN t1.id - 1 AND t1.id + 1
) subquery
WHERE rn = 1;
我觉得可能有一些更漂亮的方法可以做到这一点,但是这个问题在被问到一个小时后完全没有答案表明这不是一个容易用 SQL 解决的问题。
关于oracle - 随机化两个数据集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48794720/