从SQL数据库中选择具有相似标记(多对多关系)的行

时间:2014-03-18 04:28:53

标签: sql database

我的实体表和标签通过另一个表绑定到它(多对多关系)。

我选择了一个实体,我的目标是找到一组具有尽可能多的相似标签的实体。此套装必须按相似性排序' - 每个实体与所选实体共享的标签数量。如果标签具有相同的ID,则标签类似。

我想知道单一查询是否有优雅而快捷的方法。

我现在看到的唯一解决方案是获取所有标签 - 实体关系并在我的应用程序中计算它们的相似性,然后进行另一个数据库查询以选择我计算的内容,但它看起来并不像非常优雅。

数据库结构:

实体 ID ...

代码 ID 名称

entity_tag ENTITY_ID TAG_ID

更新:MySQL的最终解决方案。

所以我有绘画,标签和painting_tag关系的表格。此查询提取类似的绘画及其相似性指数'以前选择的绘画。

SELECT site_painting.*, Count(tr.tag_id) as similarity
From site_painting_tag_relation as tr
Inner Join site_painting_tag_relation as tr2 ON ( tr2.tag_id = tr.tag_id and tr2.painting_id = :id )
Left join site_painting on site_painting.id=tr.painting_id
Where tr.painting_id <> :id
Group By  tr.painting_id
Having Count(*) > 0
Order By  Count(*) DESC, tr.painting_id limit 1

1 个答案:

答案 0 :(得分:2)

好的,db结构的信息有很多帮助 -

entity id ...

entity_tag entity_id tag_id

tag id name

让我们看一些示例值 -

entity
  id=100
  id=...
  id=199

entity_tag
  100, 3
  100, 5
  101, 1
  102, 7
  ...
  199, 3
  199, 7

tag
  id=1
  id=...
  id=10

因此,如果我们对entity_tag进行非规范化,那么

  100   3,5
  101  1
  102       7
  199   3   7

与其余部分的相似性指数为199,范围为0到10

  100   1 in common
  101   0 in common
  102   1 in common
  199 self, no comparison

如果我说得对,我们希望显示100和102是最高的, NU?

这是对SQL的抨击 - 它可能像---

SELECT  TOP 10
FROM
(SELECT
   allET.EID,
   Count(*) as Similarity


 From entity_tag as allET

 Left Join 
      (Select * From  entity_tag  Where EID = myEID ) as myET
 On allET.TID = myET.TID

 Where allET.EID <> myEID

 Group By  allET.EID

 Having Count(*) > 0

 Order By  Count(*) DESC, allET.EID
)