sql >> Base de Datos >  >> RDS >> Mysql

comparar conjuntos de datos y obtener la mejor coincidencia

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