Sarebbe utile se ci mostrassi le strutture delle tue tabelle, così posso essere più specifico.
Presumo che tu abbia una struttura simile a questa:
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 generale, il mio approccio sarebbe iniziare contando ogni tag separato.
-- make a list of how often a tag was used:
select tagid, count(*) as `tagscore` from itemtag group by tagid
Questo mostra una riga per ogni tag che è stato assegnato all'elemento, con un punteggio.
Nel nostro esempio, sarebbe:
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
Spiegazione:La query ha 2 sottoquery:una consiste nell'ottenere i tag dell'elenco dall'elemento di interesse. Vogliamo lavorare solo con quelli. L'altra sottoquery genera un elenco di punteggi per tag.
Quindi, alla fine, ogni elemento nel database ha un elenco di punteggi dei tag. Questi punteggi vengono sommati con sum(tagscore)
, e quel numero viene utilizzato per ordinare il risultato (i punteggi più alti in cima).
Per mostrare un elenco di tag disponibili, ho utilizzato GROUP_CONCAT.
La query risulterà in qualcosa del genere (ho creato i dati effettivi qui):
Item TagsScore Tags
item3 15 red,cool,car
item4 7 red,car
item5 7 red
item1 5 car
item6 5 car