如何在 PostgreSQL 中获得随机笛卡尔积?

2024-02-17

我有两张桌子,custassets and tags。为了生成一些测试数据,我想做一个INSERT INTO一个多对多表SELECT从每个表中获取随机行(以便一个表中的随机主键与第二个表中的随机主键配对)。令我惊讶的是,这并不像我最初想象的那么容易,所以我坚持这样做来自学。

这是我的第一次尝试。我选择10custassets and 3 tags,但两者在每种情况下都是相同的。我可以修复第一个表,但我想随机分配分配的标签。

SELECT
    custassets_rand.id custassets_id,
    tags_rand.id tags_rand_id
FROM
    (
        SELECT id FROM custassets WHERE defunct = false ORDER BY RANDOM() LIMIT 10
    ) AS custassets_rand
,
    (
        SELECT id FROM tags WHERE defunct = false ORDER BY RANDOM() LIMIT 3
    ) AS tags_rand

这会产生:

custassets_id | tags_rand_id 
---------------+--------------
          9849 |         3322  }
          9849 |         4871  } this pattern of tag PKs is repeated
          9849 |         5188  }
         12145 |         3322
         12145 |         4871
         12145 |         5188
         17837 |         3322
         17837 |         4871
         17837 |         5188
....

然后我尝试了以下方法:执行第二个RANDOM()调用SELECT列列表。然而这个更糟糕,因为它选择单个标签 PK 并坚持下去。

SELECT
    custassets_rand.id custassets_id,
    (SELECT id FROM tags WHERE defunct = false ORDER BY RANDOM() LIMIT 1) tags_rand_id
FROM
    (
        SELECT id FROM custassets WHERE defunct = false ORDER BY RANDOM() LIMIT 30
    ) AS custassets_rand

Result:

 custassets_id | tags_rand_id 
---------------+--------------
         16694 |         1537
         14204 |         1537
         23823 |         1537
         34799 |         1537
         36388 |         1537
....

这对于脚本语言来说很容易,而且我确信使用存储过程或临时表可以很容易地完成。但我可以只用一个INSERT INTO SELECT?

我确实考虑过使用随机函数选择整数主键,但不幸的是两个表的主键在增量序列中都有间隙(因此每个表中可能会选择一个空行)。不然就好了!


请注意,您正在寻找的是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 添加的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 PostgreSQL 中获得随机笛卡尔积? 的相关文章

随机推荐

  • SQL Server 2k5内存消耗?

    我有一个正在运行 sql server 的开发虚拟机以及我的堆栈的一些其他应用程序 我发现其他应用程序的性能非常糟糕 经过一番挖掘后 SQL Server 占用了内存 经过快速的网络搜索后 我发现默认情况下 它会消耗尽可能多的内存来缓存数据
  • Java 反射,getMethod()

    我正在研究 Java 反射的基础知识并观察类方法的信息 我需要获取一个与 getMethod 函数所描述的规范相匹配的方法 然而 当我这样做时 我得到一个 NoSuchMethodException 我希望你能告诉我为什么我的实现不正确 s
  • 如何删除旧版 Web 应用程序中的 CSS 意大利面?

    在开发了几个大型 Web 应用程序并看到没有清晰结构的巨大样式表之后 我真的很想知道人们是否找到了方法来保持大型复杂 Web 应用程序的 CSS 干净 如何从遗留的 混乱的 CSS 转向干净的 漂亮的级联 DRY 样式表 我目前正在开发的应
  • 为什么不使用工厂模式进行排序? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 有没有一种优雅的方法来解析单词并在大写字母前添加空格

    我需要解析一些数据并且我想转换 AutomaticTrackingSystem to Automatic Tracking System 本质上是在任何大写字母之前放置一个空格 当然除了第一个字母 您可以使用环视 例如 string tes
  • 在 Mac 上覆盖 python 3.x 中的打印行

    我正在尝试编写一个涉及使用硬币翻转 正面或反面的程序 但这样它会打印 正面 然后用 反面 替换 并继续这样做 直到决定答案 目前 当我运行该程序时 它每次都会在下一行打印 正面 或 背面 这种情况在空闲和终端上都会发生 我尝试过使用回车符
  • 在运行时创建证书和通行证类型 ID

    我的 Passbook 相关应用最近根据准则 23 3 被拒绝 23 3 通行证必须由将以其自己的名称 商标或品牌分发通行证的实体签署 否则应用程序将被拒绝 并且 Passbook 凭据可能会被撤销 我有几个问题 并与苹果公司的某人通了电话
  • jQuery 和 IE 在 $('#someDiv').hide(); 上崩溃

    好吧 过了一会儿我挠了挠头 啊 试图找出为什么 IE 在加载我的一个加载了 jQuery 的页面时会直接崩溃 我将罪魁祸首缩小到这一行 div questions hide 当我说 IE 崩溃时 我的意思是它完全崩溃了 试图进行网页恢复 但
  • 在 https:// 上使用 ws://(混合内容)

    我有一个 html5 页面 var connection new WebSocket ws foo bar 8888 但我收到一个错误 混合内容 页面位于 https foo bar https foo bar 通过 HTTPS 加载 但尝
  • PHP PDO 准备好的语句需要转义吗?

    On the PDO 准备页面 http www php net manual en pdo prepare php它指出 并且无需手动引用参数 有助于防止 SQL 注入攻击 知道了这一点 是否有像 mysql real escape st
  • 将 git 与 CVS 结合使用的最佳实践

    使用 git 与 CVS 存储库交互的最佳实践和技巧是什么 我写了一个类似问题的答案here https stackoverflow com questions 584522 how to export revision history f
  • 按钮是否允许显示:网格? [复制]

    这个问题在这里已经有答案了 按钮是否允许显示 网格 或者更一般地说 是否有任何元素不能使用display grid 考虑 button div display grid grid template columns 50px 50px Nev
  • 从 DOS 命令行关闭正在运行的应用程序

    start 命令可以在批处理文件中启动像记事本这样的应用程序 如下所示 start notepad start my love mp3 但是如何从命令行关闭正在运行的应用程序呢 我发现taskkill在我的搜索中 但我认为这不是正确的命令
  • 如何显示当前运行的python模块的路径? [复制]

    这个问题在这里已经有答案了 如何显示当前运行的python模块的路径 哪个会打印 Users user documents python bla py如果 bla py 被放置在 Users user documents python 如果
  • 将二进制格式字符串转换为 int,在 C 中

    如何将二进制字符串 如 010011101 转换为 int 以及如何将 int 如 5 转换为 C 中的字符串 101 The strtol标准库中的函数采用 base 参数 在本例中为 2 int fromBinary const cha
  • S3 上的静态网站,路由为 53 - 无法访问网站

    我在 S3 上托管了一个静态网站 并设置了合适的存储桶策略 在另一个选项卡中查看 端点 效果非常好 此后 我在路线 53 中创建了一个托管区域 为其提供了理想的人类可读地址 创建托管区域后 我新创建的托管区域中有两条记录 其中一条记录属于类
  • Django 根据子级过滤父级

    我有发票型号 class Invoice models Model name models ForeignKey Patient on delete models CASCADE 我有另一个发票金额模型 其中包含发票的 FK class I
  • Firebase 远程通知未收到?

    我尝试通过云消息从 Firebase 控制台发送远程通知 但我的手机没有收到任何警报 我已将证书上传到 Firebase 并且正在使用 Firebase 教程提供的默认代码来接收通知 Here is a picture of my cert
  • tkinter OptionMenu 问题(bug?):GUI 和程序值未保持同步(python 3.x)

    在某些情况下 下面的演示 OpenMenu 小部件上显示的值与程序使用的值不匹配 这会导致当用户期望选项 A 时执行选项 B 导致 WTF 用户的反应 不幸的是 OptionMenu 小部件没有我与其他小部件一起使用来轻松处理问题的 命令
  • 如何在 PostgreSQL 中获得随机笛卡尔积?

    我有两张桌子 custassets and tags 为了生成一些测试数据 我想做一个INSERT INTO一个多对多表SELECT从每个表中获取随机行 以便一个表中的随机主键与第二个表中的随机主键配对 令我惊讶的是 这并不像我最初想象的那