Sería útil si nos mostraras las estructuras de tus tablas, para que pueda ser más específico.
Supongo que tienes una estructura que se parece a esto:
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 general, mi enfoque sería comenzar contando cada etiqueta por separado.
-- make a list of how often a tag was used:
select tagid, count(*) as `tagscore` from itemtag group by tagid
Esto muestra una fila para cada etiqueta que se asignó al elemento, con una puntuación.
En nuestro ejemplo, sería:
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
Explicación:La consulta tiene 2 subconsultas:Una es para obtener las etiquetas de lista del elemento de interés. Solo queremos trabajar con esos. La otra subconsulta genera una lista de puntajes por etiqueta.
Entonces, al final, cada elemento en la base de datos tiene una lista de puntajes de etiquetas. Esas puntuaciones se suman con sum(tagscore)
, y ese número se usa para ordenar el resultado (puntajes más altos en la parte superior).
Para mostrar una lista de etiquetas disponibles, he usado GROUP_CONCAT.
La consulta dará como resultado algo como esto (he creado los datos reales aquí):
Item TagsScore Tags
item3 15 red,cool,car
item4 7 red,car
item5 7 red
item1 5 car
item6 5 car