为 SQL 连接选择单个(随机)行

Posted

技术标签:

【中文标题】为 SQL 连接选择单个(随机)行【英文标题】:Selecting a single (random) row for an SQL join 【发布时间】:2009-09-28 13:24:30 【问题描述】:

我有一个从多个表中选择数据的 sql 查询,但我只想匹配另一个表中的单个(随机选择)行。

我想更容易显示一些代码;)

表 K 是 (k_id, selected) 表 C 是 (c_id, image) 表 S 是 (c_id, date) 表M为(c_id, k_id, score)

所有 ID 列都是主键,具有适当的 FK 约束。

我想要的,用英语,是 K 中选择 = 1 的 eack 行从 C 中获取随机行,其中 M 中存在一行(K_id,C_id),其中分数高于给定值,其中 c.image 不为 null 且 s 中有一行带有 c_id

类似:

select k.k_id, c.c_id, m.score
 from k,c,m,s
where k.selected = 1
  and m.score > some_value
  and m.k_id = k.k_id
  and m.c_id = c.c_id
  and c.image is not null
  and s.c_id = c.c_id;

唯一的问题是这会返回 C 中符合条件的所有行 - 我只想要一个...

我可以看到如何使用 PL/SQL 将所有相关行选择到一个集合中,然后选择一个随机行,但我不知道如何选择一个随机行。

【问题讨论】:

【参考方案1】:

您可以在查询中使用“按 dbms_random.random 排序”指令。

即:

SELECT column FROM
  (
    SELECT column FROM table
    ORDER BY dbms_random.value
  )
WHERE rownum = 1

参考资料: http://awads.net/wp/2005/08/09/order-by-no-order/ http://www.petefreitag.com/item/466.cfm

【讨论】:

【参考方案2】:

使用分析:

SELECT k_id, c_id, score
  FROM (SELECT k.k_id, c.c_id, m.score, 
               row_number() over(PARTITION BY k.k_id ORDER BY NULL) rk
           FROM k, c, m, s
          WHERE k.selected = 1
            AND m.score > some_value
            AND m.k_id = k.k_id
            AND m.c_id = c.c_id
            AND c.image IS NOT NULL
            AND s.c_id = c.c_id)
 WHERE rk = 1

这将为每个 k_id 选择满足您的条件的一行。如果您多次运行查询,这可能会选择同一组行。如果您想要更多随机性(每次运行产生一组不同的行),您可以将 ORDER BY NULL 替换为 ORDER BY dbms_random.value

【讨论】:

ORDER BY NULL 可能不会生成随机顺序。不可预测,是的,但不是随机的。这些行将(很可能)按照它们存储在索引中的顺序或从它们读取的任何位置返回,这可能对 OP 来说足够好,也可能不够好。 @erikkallen> 我同意,我更新了我的答案,增加了随机性以增加不可预测性:> 完美! - 看起来 PARTITION BY 是关键。谢谢。【参考方案3】:

我对 oracle SQL 不太熟悉,但如果有这样的函数可用,请尝试使用 LIMIT random()。

【讨论】:

Oracle SQL 不支持 LIMIT 关键字。 确实如此,只需将其称为 rownum ... 并且 rownum

以上是关于为 SQL 连接选择单个(随机)行的主要内容,如果未能解决你的问题,请参考以下文章

从表中随机选择行 - Python Pandas 读取 SQL

从表中随机选择行 - Python Pandas Read SQL

随机 10% 的 SQL 查询,最少 20 行

通过 JPA 随机选择行

SQL 查询来自不同区域的选择行

随机名称表中的 SQL 更新