【问题标题】:Select random rows but without duplicates of values from another column选择随机行但不重复另一列中的值
【发布时间】:2019-03-14 17:39:59
【问题描述】:

我有以下查询,它给了我 3 个随机名称、ids 和 top_tags:

SELECT  Name
     , id
     , top_tag 
  FROM artists 
 WHERE  not find_in_set (id,'1,2,3,4') 
 order 
    by rand() 
 limit 3

它工作正常,但是,我确实需要另一个条件。 我有一个列名 top_tag (int),我需要结果将包含 3 个唯一的 top_tag 值,而不是 top_tag 的重复项。

【问题讨论】:

  • not find_in_set() 应该做什么?你听说过not in吗?
  • @Strawberry 已更新,谢谢。从 C# 复制查询时,它被删除了。请注意,not find_in_set() 与问题并没有真正的关系,但我只是在查询中使用它。
  • @GordonLinoff not in 也可以。 find_in_set 与您所指的非常相似。 [链接]dev.mysql.com/doc/refman/8.0/en/…
  • 结果相似,但FIND_IN_SET() 不会使用索引,而NOT IN() 会。
  • @BillKarwin 注意到

标签: mysql sql random


【解决方案1】:

在 MySQL 8+ 中,您将使用窗口函数:

SELECT Name, id, top_tag 
FROM (SELECT a.*, ROW_NUMBER() OVER (PARTITION BY top_tag ORDER BY rand()) as seqnum
      FROM artists a
      WHERE id NOT IN (1, 2, 3, 4) 
     ) a
WHERE seqnum = 1
LIMIT 3;

【讨论】:

  • LIMIT 是否保留了随机性,或者我们的某些行比其他行更有可能被排除在外?
  • a.* 需要更改为 * 才能使查询正常工作。
  • @Strawberry 。 . .随机行是随机行。如果你取第一个 ,那是一个随机样本。最后一个 或者实际上是独立于行中的值选择的任何 也是如此。
【解决方案2】:

与 Gordon 的回答类似,但这可以确保三个不同且随机的 top_tags:

SELECT Name, id, top_tag
FROM (
    SELECT name, id, top_tag, 
      ROW_NUMBER() OVER (PARTITION BY top_tag ORDER BY RAND()) AS seqnum
    FROM (
      SELECT DISTINCT top_tag FROM artists 
      WHERE id NOT IN (1,2,3,4) 
      ORDER BY RAND() LIMIT 3) AS t
    JOIN artists AS a ON (t.top_tag = a.top_tag)
    WHERE a.id NOT IN (1,2,3,4)
) AS x
WHERE seqnum = 1

或者您可以坚持使用原始查询,但增加样本量:

SELECT Name, id, top_tag 
FROM artists 
WHERE id NOT IN (1,2,3,4)
ORDER BY RAND() LIMIT 30 

然后在您的应用中,获取更多结果,直到三行具有不同的 top_tag 值,丢弃您已经获取的任何 top_tag 值的行。如果您通过了所有 30 个但仍未获得三个不同的标签,请再试一次(但请注意不要无限期地重试,因为如果您的数据不包含两个以上不同的 top_tag,这将导致无限循环值)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-23
    • 2022-07-18
    • 2012-10-22
    • 2023-02-02
    • 2014-09-10
    • 1970-01-01
    • 2020-01-26
    相关资源
    最近更新 更多