Mysql
 sql >> Base de données >  >> RDS >> Mysql

comparer des ensembles de données et renvoyer la meilleure correspondance

Il serait utile que vous nous montriez vos structures de table, afin que je puisse être plus précis.

Je suppose que vous avez une structure qui ressemble à ceci :

Table item: (id, itemname)
1 item1
2 item2
3 item3
4 item4
5 item5

Table tag: (id, tagname)
1 cool
2 red
3 car

Table itemtag: (id, itemid, tagid)
1 1 2 (=item1, red)
2 2 1 (=item2, cool)
3 2 3 (=item2, car)
4 3 1 (=item3, cool)
5 3 2 (=item3, red)
6 3 3 (=item3, car)
7 4 3 (=item3, car)
8 5 3 (=item3, car)

En général, mon approche serait de commencer par compter chaque balise séparément.

-- make a list of how often a tag was used:
select tagid, count(*) as `tagscore` from itemtag group by tagid

Cela affiche une ligne pour chaque balise qui a été attribuée à l'élément, avec un score.

Dans notre exemple, ce serait :

tag  tagscore
1    2         (cool, 2x)
2    2         (red, 2x)
3    4         (car, 4x)


set @ItemOfInterest=2;

select
  itemname,
  sum(tagscore) as `totaltagscore`,
  GROUP_CONCAT(tags) as `tags`
from
  itemtag
join item on itemtag.itemid=item.id

join
  /* join the query from above (scores per tag) */
  (select tagid, count(*) as `tagscore` from itemtag group by tagid ) as `TagScores`
  on `TagScores`.tagid=itemtag.tagid
where
  itemid<>@ItemOfInterest and 
  /* get the taglist of the current item */
  tagid in (select distinct tagid from itemtag where [email protected])
group by
  itemid
order by
  2 desc

Explication :La requête comporte 2 sous-requêtes :la première consiste à obtenir les balises de la liste à partir de l'élément qui vous intéresse. Nous ne voulons travailler qu'avec ceux-ci. L'autre sous-requête génère une liste de scores par balise.

Ainsi, au final, chaque élément de la base de données a une liste de scores de balises. Ces scores sont additionnés avec sum(tagscore) , et ce nombre est utilisé pour ordonner le résultat (scores les plus élevés en haut).

Pour afficher une liste des balises disponibles, j'ai utilisé GROUP_CONCAT.

La requête donnera quelque chose comme ceci (j'ai créé les données réelles ici) :

Item   TagsScore   Tags
item3  15          red,cool,car
item4   7          red,car
item5   7          red
item1   5          car
item6   5          car