【问题标题】:SQL find close matchesSQL 查找接近的匹配项
【发布时间】:2011-09-05 04:56:40
【问题描述】:

我正在尝试为产品构建过滤系统。产品有许多属性,包括价格、尺寸(厘米)和边数(# of)。我想构建一个 SQL 查询,该查询始终返回 ALL 产品,但根据它们满足搜索条件的程度对它们进行排序。

例如,假设我有以下产品:

产品 A 价格:250 尺寸:50 边数:4

产品 B 价格:300 尺寸:60 边数:3

产品 C 价格:200 尺寸:60 边数:5

并且有一个搜索条件:

价格:$210 - $260

我希望它返回: 产品A、产品C、产品B

A 是第一个,因为它满足所有搜索条件。 C 领先于 B,因为 200 美元比 300 美元更接近 210-260 美元的范围。

这是一个相当简单的案例,但搜索可能涉及任何属性。

我脑海中的算法正在为每个属性进行某种标准偏差计算,这将为您提供该属性与搜索条件的接近程度的“分数”,这些分数可以在产品中进行总结,以给出产品相关性的总分。这是在正确的轨道上吗?

我意识到这是一个相当复杂的问题,我真的只是在寻找一些指导而不是任何事情。

【问题讨论】:

  • 我认为您的 A、B 和 C 混淆了。 B应该首先返回,因为它在价格范围内。 C 应返回第二个(超出范围 10 美元),然后是 A(超出范围 40 美元)。
  • 哎呀...你是对的。我会进行编辑。

标签: php mysql database oracle postgresql


【解决方案1】:

您基本上必须为每一行提供一个“距离”函数,如果所有条件都匹配,则返回 0,否则返回某个正值,表示距离有多近。每个不同的列都必须有一定的权重,因为偏离 1 美元并不像偏离 1 个边那样远。对于低于 210 的价格,未加权距离将为(210 - 价格),如果价格高于 260,则价格列的未加权距离为(价格 - 260)。然后您可以将加权距离 w1 * price_distance + w2 * size_distance + s3 * side_distance 相加。然后你可以按距离订购。

【讨论】:

  • 正是我需要的!谢谢!
【解决方案2】:

如何计算平均值,然后按与该平均值的偏差排序?我在想象这样的事情(显然,您的表/列名称会有所不同):

SELECT
  p.price,
  p.size,
  p.sides,
  ABS(p.price - 235) AS distance
FROM
  products p
ORDER BY
  distance;

当然,您可能还想加入一个 IF 函数来评估价格是否在该范围内,我建议在后面使用参数化查询,而不是直接输入平均值。

【讨论】:

  • 根据其他评论者,您可能还想为每个属性分配一个权重,将它们相互标准化,然后将它们相加。例如,ABS(p.price - 235) * 0.2 AS price_distance,ABS(p.size - 45) * 2.5 AS size_distance,ABS(p.sides - 3) * 20 AS side_distance,price_distance + size_distance + side_difference AS total_deviation。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-29
相关资源
最近更新 更多