【问题标题】:SQL: Limit and Randomize results in joinSQL:连接中的限制和随机化结果
【发布时间】: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,在一两周内,当我们有好的样本数据时,我会看到它的表现。

标签: mysql select join random limit


【解决方案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

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-14
  • 2014-10-12
  • 2020-08-14
  • 2011-01-17
  • 2012-12-13
相关资源
最近更新 更多