Het zou helpen als je ons je tabelstructuren laat zien, zodat ik specifieker kan zijn.
Ik neem aan dat je een structuur hebt die hier op lijkt:
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)
In het algemeen zou mijn benadering zijn om te beginnen met het tellen van elke afzonderlijke tag.
-- make a list of how often a tag was used:
select tagid, count(*) as `tagscore` from itemtag group by tagid
Dit toont een rij voor elke tag die aan het item is toegewezen, met een score.
In ons voorbeeld zou dat zijn:
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
Uitleg:De query heeft 2 subquery's:Een daarvan is om de lijsttags van het item van belang te verkrijgen. Alleen daarmee willen we werken. De andere subquery genereert een lijst met scores per tag.
Dus uiteindelijk heeft elk item in de database een lijst met tagscores. Die scores worden opgeteld met sum(tagscore)
, en dat nummer wordt gebruikt om het resultaat te ordenen (hoogste scores bovenaan).
Om een lijst met beschikbare tags weer te geven, heb ik GROUP_CONCAT gebruikt.
De zoekopdracht zal resulteren in iets als dit (ik heb de feitelijke gegevens hier gemaakt):
Item TagsScore Tags
item3 15 red,cool,car
item4 7 red,car
item5 7 red
item1 5 car
item6 5 car