MySQL如何通过多个属性行的相似性对对象进行排名
Posted
技术标签:
【中文标题】MySQL如何通过多个属性行的相似性对对象进行排名【英文标题】:MySQL how to rank objects by similarity of multiple property rows 【发布时间】:2012-12-16 04:26:47 【问题描述】:大家好,新年快乐
情况:
我在 mysql 数据库中有一些表:
分数: (唯一 ID,唯一(objectID,metricID))
| ID | ObjectID | MetricID | Score |
|--------+----------+----------+----------|
|0 | 1 | 7 | 0 |
|1 | 5 | 3 | 13 |
|2 | 7 | 2 | 78 |
|3 | 7 | 3 | 22 |
|.....
|--------+----------+----------+----------|
对象: (唯一 ID,唯一 ObjectName)
| ID | ObjectName |
|--------+------------|
|0 | Ook |
|1 | Oop |
|2 | Oww |
|3 | Oat |
|.....
|--------+------------|
指标: (唯一 ID,唯一 MetricName)
| ID | MetricName |
|--------+------------|
|0 | Moo |
|1 | Mar |
|2 | Mee |
|3 | Meep |
|.....
|--------+------------|
对于给定的对象 ID:
在“0”和“每个指标一个”之间会有许多分数要求:
对于给定的 ObjectID,我想根据以下条件返回一个排序列表:
返回的行按与所提供对象的相似度排序 返回的行不包括提供的对象 (这是我认为的难点)相似性顺序由对象与提供的对象的“得分距离”决定,基于其得分与提供的对象得分的数字偏移量/差异,用于任何度量标准提供的和当前检查的对象的条目 包含对象 ID、对象名称、分数差异(或类似内容)问题说明:
我不知道为此使用的正确 SQL 语法,而且我的实验到目前为止都失败了。我想尽可能多地在数据库中完成这项工作,并且很少或根本没有在代码中的讨厌的 for 循环或类似内容中完成这些工作。
其他非函数
目前,Scores 表中只有 200 行。我的计算表明,最终可能会有大约 2,000,000 行,但可能不会更多。 Objects 表最多只能有大约 5000 行 Metrics 表最多只能有大约 400 行【问题讨论】:
你一定是个软件工程师。 +1 以非常好的格式提问 你能从样本数据中显示预期的输出吗? 我很难理解您对相似顺序的描述。 score distance 和 score offset 一样吗? 提供的对象是否与搜索的对象相同? 感谢您的反馈。 Hanky Panky - 我不是专业的软件工程师,但我确实从事 IT 工作。 Barmar - 稍微编辑了文本,希望能更好地澄清一点。 【参考方案1】:这是一种根据对象与对象 1 的相似性对对象进行排序的方法:
select other.ObjectID
, avg(abs(target.Score - other.Score)) as Delta
from Scores target
join Scores other
on other.MetricID = target.MetricID
and other.ObjectID <> target.ObjectID
where target.ObjectID = 1
group by
other.ObjectID
order by
Delta
相似度定义为常见指标的平均差异。未列出不与对象 1 共享至少一个度量的对象。如果此答案做出错误假设,请随时澄清您的问题:)
Live example at SQL Fiddle.
【讨论】:
感谢您的回答。这看起来不错,只是稍微适应我的实际情况(稍微不那么通用)并在接受答案之前进行验证。 我已经根据一个真实的数据集验证了这个答案的稍微修改的版本对我来说非常有效,因此将其标记为已接受。通过阅读并了解您的解决方案的工作原理,我还学到了很多关于如何思考这些东西的知识。很棒的东西,谢谢。以上是关于MySQL如何通过多个属性行的相似性对对象进行排名的主要内容,如果未能解决你的问题,请参考以下文章
如何通过 valueForKey 从 fetch 中对数组进行排序