MySQL如何通过多个属性行的相似度对对象进行排名

spe*_*uce 5 mysql sql database select

大家好,新年快乐

情况:

我在 MySQL 数据库中有一些表:

分数:(唯一ID,唯一(objectID,metricID))

| ID     | ObjectID | MetricID | Score    |
|--------+----------+----------+----------|
|0       | 1        | 7        | 0        | 
|1       | 5        | 3        | 13       |
|2       | 7        | 2        | 78       |
|3       | 7        | 3        | 22       |
|.....
|--------+----------+----------+----------|
Run Code Online (Sandbox Code Playgroud)

对象:(唯一 ID、唯一对象名称)

| ID     | ObjectName |
|--------+------------|
|0       | Ook        | 
|1       | Oop        |
|2       | Oww        |
|3       | Oat        |
|.....
|--------+------------|
Run Code Online (Sandbox Code Playgroud)

指标:(唯一 ID、唯一 MetricName)

| ID     | MetricName |
|--------+------------|
|0       | Moo        | 
|1       | Mar        |
|2       | Mee        |
|3       | Meep       |
|.....
|--------+------------|
Run Code Online (Sandbox Code Playgroud)

对于给定的对象 ID:

  • 会有“0”和“每个指标一个”之间的多个分数

要求:

对于给定的 ObjectID,我想根据以下条件返回排序列表:

  • 返回的行按与提供的对象的相似度排序
  • 返回的行不包含提供的对象
  • (我认为这是一个难点)相似性的顺序是由对象与提供的对象的“分数距离”确定的,该“分数距离”基于其分数与提供的对象的分数之间的数字偏移/差异,对于任何有条目的指标提供的对象和当前检查的对象
  • 包含objectID,对象名称,分数差异(或类似的东西)

问题陈述:

我不知道用于此目的的正确 SQL 语法,并且迄今为止我的实验都失败了。我希望在数据库中尽可能多地完成这些工作,并且很少或根本不在代码或类似的讨厌的 for 循环中完成这些工作。

额外的非功能性物质

  • 目前 Scores 表中只有 200 行。我的计算显示最终可能最多有 2,000,000 行左右,但可能不会更多。
  • Objects 表最多只有 5000 行左右
  • Metrics 表最多只有 400 行左右

And*_*mar 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
Run Code Online (Sandbox Code Playgroud)

相似性定义为共同指标的平均差异。不与对象 1 共享至少一项指标的对象不会列出。如果这个答案做出了错误的假设,请随时澄清您的问题:)

SQL Fiddle 的实时示例。