【问题标题】:Get multiple unique random rows for tags in MySql from one reference table从一个引用表中获取 MySql 中标签的多个唯一随机行
【发布时间】:2012-03-01 15:18:35
【问题描述】:

我有一张表,其中标签和项目之间的引用存储在我的数据库中,格式为

id - tagID - itemID 1 - 1 - 1 2 - 2 - 1 3 - 1 - 2 4 - 3 - 2 5 - 4 - 2

我输入了当前的 itemID,并且我想为该项目的每个标签选择一个其他随机项目 ID。

显而易见的方法是运行一个查询来选择该项目的标签,然后针对每个标签运行一个查询来为每个标签选择不同的 itemID。

例如对于 itemID “1”

SELECT tagID FROM mytags WHERE itemID=1

然后foreach tagID "X"

SELECT itemID FROM mytags WHERE tagID= "X" AND itemID!=1

但是如果一个项目有 10 个标签,这将导致 11 个查询仅针对我的应用程序的这一部分。

我正在尝试找到一种方法来运行单个 SQL 以获得相同的结果。

下面是一个好的开始

SELECT tagID, itemID
FROM `mytags`
WHERE tagID IN ( SELECT tagID
                 FROM `mytags`
                 WHERE itemID =1 )
AND itemID !=1

但这会返回该项目标签的所有其他行,而我只想要其中一个。

有人有什么好主意吗?

谢谢

【问题讨论】:

  • 如果您只想要其中一个,为什么不在查询中添加LIMIT 1
  • 因为“限制 1”会给我一个标签中的一个项目。我想要每个标签一个项目。

标签: mysql


【解决方案1】:

与大多数情况下随机选择一样,有很多参数可以在组合查询中执行此操作:您将不得不ORDER BY RAND() 这是性能杀手。我的建议是要么用你周围的语言工作,要么创建一个激动人心的程序:

  • SELECT DISTINCT tagID FROMmytagsWHERE itemID=1声明一个游标
  • 循环这个光标在做
  • SELECT MAX(id) INTO maxid FROMmytagsWHERE tagID=current_tag_from_cursor AND itemID<>1
  • SELECT itemID FROMmytagsWHERE tagID=current_tag_from_cursor AND itemID<>1 AND id>CAST(FLOOR(RAND()*maxid) AS UNSIGNED)

是的,你做了很多查询。 是的,在大于几千行的表上,这仍然比 ORDER BY RAND() 提供更好的性能

【讨论】:

  • The ORDER BY RAND() 我确实通过在 php 中工作来避免它(通过在 X 上获取第一项,其中 X 我在 php 中计算)。我将研究如何/是否可以在我的环境中使用存储过程。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-23
  • 1970-01-01
  • 1970-01-01
  • 2020-12-05
  • 1970-01-01
相关资源
最近更新 更多