请注意,您正在寻找的是not a 笛卡尔积 https://en.wikipedia.org/wiki/Cartesian_product,这会产生n*m
行;而是随机的 1:1 关联,这会产生GREATEST(n,m)
rows.
生产真正随机的组合,随机化就足够了rn
对于更大的集合:
SELECT c_id, t_id
FROM (
SELECT id AS c_id, row_number() OVER (ORDER BY random()) AS rn
FROM custassets
) x
JOIN (SELECT id AS t_id, row_number() OVER () AS rn FROM tags) y USING (rn);
If 随意的组合足够好,这更快(特别是对于大表):
SELECT c_id, t_id
FROM (SELECT id AS c_id, row_number() OVER () AS rn FROM custassets) x
JOIN (SELECT id AS t_id, row_number() OVER () AS rn FROM tags) y USING (rn);
如果两个表中的行数不匹配,并且您不想丢失较大表中的行,请使用模运算符% https://www.postgresql.org/docs/current/functions-math.html多次连接较小表中的行:
SELECT c_id, t_id
FROM (
SELECT id AS c_id, row_number() OVER () AS rn
FROM custassets -- table with fewer rows
) x
JOIN (
SELECT id AS t_id, (row_number() OVER () % small.ct) + 1 AS rn
FROM tags
, (SELECT count(*) AS ct FROM custassets) AS small
) y USING (rn);
窗口函数 https://www.postgresql.org/docs/current/functions-window.html是随 PostgreSQL 8.4 添加的。