SQL:连接中的限制和随机化结果

Posted

技术标签:

【中文标题】SQL:连接中的限制和随机化结果【英文标题】:SQL: Limit and Randomize results in join 【发布时间】:2013-01-07 10:49:38 【问题描述】:

我正在构建一个可以在附近位置查找商品的购物系统。基本上,每个位置(供应商)在一个名为 Location 的表中都有一个条目,其中包含名称、纬度、经度和其他列......然后有一个项目表,带有一个外键,用于标识项目所属的位置到。

基本上,我想找到用户附近的所有项目:我可以使用以下查询来完成:

但是我想执行以下操作 - 从该位置随机选择物品 - 将每个位置的项目数量限制在少数(比如 5 个) - 随机化所有结果,使其不按位置分组

到目前为止,这是我完成的最困难的查询,我正在变得更好,但我一直坚持这个问题 - 如果非常感谢,请提供任何帮助!谢谢!!

到目前为止,这是我的选择语句:

SELECT Location.idLocation
 , Location.locationName
 , Location.tagline
 , Location.tags
 , Location.shortAddress
 , (3959 * acos(cos(radians('40.181')) * cos(radians(Location.latitude)) * cos(radians(Location.longitude) - radians('-74.0265')) + sin(radians('40.181')) * sin(radians(Location.latitude)))) AS distance
 , Item.idItem
 , Item.dateAdded
 , Item.fidLocation
 , Item.itemName
 , Item.description
 , Item.fullImageName
 , Item.thumbnailImageName
FROM
  Location
INNER JOIN Item
ON Location.idLocation = Item.fidLocation
HAVING distance < '1000'

【问题讨论】:

order by rand() limit 5 是快速/肮脏/便宜/昂贵的方法。 你想从每个位置随机选择5个项目然后你想如何订购它们? 谢谢。是的,每个位置最多 5 件商品,而不是总共 5 件商品。 您能否提供具有所需输出的表结构和示例数据 raheel,将把它放在一起并发布。不要以为我完全回答了你的问题。这背后的想法是帮助人们发现他们周围的事物,而数据结构非常好,结果应该是来自不同供应商的搜索范围内的项目的非常多样化的分布。我尝试了 Marc B 的建议,只按 rand 排序结果,现在这似乎工作正常。我们还没有输入庞大的数据集进行测试,所以我想我现在会坚持使用 rand,在一两周内,当我们有好的样本数据时,我会看到它的表现。 【参考方案1】:

好的。这是基于假设的未经测试的版本。

SELECT
  Location.idLocation,
  Location.locationName,
  Location.tagline,
  Location.tags,
  Location.shortAddress,
  (3959 * acos(cos(radians('40.181')) * cos(radians(Location.latitude)) * cos(radians(Location.longitude) - radians('-74.0265')) + sin(radians('40.181')) * sin(radians(Location.latitude)))) AS distance,
  Item.idItem,
  Item.dateAdded,
  Item.fidLocation,
  Item.itemName,
  Item.description,
  Item.fullImageName,
  Item.thumbnailImageName
FROM Location
  INNER JOIN (select *
          from Item
          order by RAND()
          limit 5) as Item
    ON Location.idLocation = Item.fidLocation
ORDER BY RAND()
HAVING distance < '1000'

【讨论】:

这只会选择总共 5 个项目,而不是每个位置 5 个。然后它会过滤掉任何超过 1,000 英里(或公里,我不确定)的东西,所以你可能什么也得不到。 去掉限制五的结果是什么? 然后你会得到一切,就像问题中的查询一样。 谢谢 Raheel,试过了,但是 Barmar 是正确的。总共选择 5 个项目。【参考方案2】:
SET @local = 0;
SET @group = 0;

SELECT Location.idLocation
 , Location.locationName
 , Location.tagline
 , Location.tags
 , Location.shortAddress
 , (3959 * acos(cos(radians('40.181')) * cos(radians(Location.latitude)) * cos(radians(Location.longitude) - radians('-74.0265')) + sin(radians('40.181')) * sin(radians(Location.latitude)))) AS distance
 , Item.idItem
 , Item.dateAdded
 , Item.fidLocation
 , Item.itemName
 , Item.description
 , Item.fullImageName
 , Item.thumbnailImageName
 , @level := IF(@group = idLocation, @level+1, 1) AS level
 , @group := idLocation as tempGroup 
FROM
  Location
INNER JOIN Item
ON Location.idLocation = Item.fidLocation
order by idLocation, RAND(),
HAVING distance < '1000' AND level <= 5

【讨论】:

感谢 Barmar,这有点用。 @ 运算符叫什么,所以我可以查找并了解它 @ 不是运算符,它是用户定义变量所需的前缀。 dev.mysql.com/doc/refman/5.6/en/user-variables.html

以上是关于SQL:连接中的限制和随机化结果的主要内容,如果未能解决你的问题,请参考以下文章

随机化一个整数数组[重复]

随机化表格单元格

如何在 C# 中的石头、纸、剪刀游戏中随机化数组中的变量? [复制]

是否可以使用 VTL 随机化 DynamoDB 查询结果?

临床试验随机化分组及其SAS实现-分层随机化

随机化在计算机中的应用:查找和搜索以及信息加密