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

¿Filtrado colaborativo en MySQL?

Cree una tabla e inserte los datos de prueba:

CREATE TABLE `ub` (
  `user_id` int(11) NOT NULL,
  `book_id` varchar(10) NOT NULL,
  PRIMARY KEY (`user_id`,`book_id`),
  UNIQUE KEY `book_id` (`book_id`,`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

insert into ub values (1, 'A'), (1, 'B'), (1, 'C');
insert into ub values (2, 'A'), (2, 'B'), (2, 'C'), (2,'D');
insert into ub values (3, 'X'), (3, 'Y'), (3, 'C'), (3,'Z');
insert into ub values (4, 'W'), (4, 'Q'), (4, 'C'), (4,'Z');

Una los datos de prueba en sí mismos por book_id y cree una tabla temporal para contener cada user_id y la cantidad de libros que tiene en común con el user_id de destino:

create temporary table ub_rank as 
select similar.user_id,count(*) rank
from ub target 
join ub similar on target.book_id= similar.book_id and target.user_id != similar.user_id
where target.user_id = 1
group by similar.user_id;

select * from ub_rank;
+---------+------+
| user_id | rank |
+---------+------+
|       2 |    3 |
|       3 |    1 |
|       4 |    1 |
+---------+------+
3 rows in set (0.00 sec)

Podemos ver que user_id tiene 3 en común con user_id 1, pero user_id 3 y user_id 4 solo tienen 1 cada uno.

A continuación, seleccione todos los libros que tienen los usuarios en la tabla temporal que no coinciden con los libros del user_id de destino y organícelos por rango. Tenga en cuenta que el mismo libro puede aparecer en diferentes listas de usuarios, por lo que sumamos las clasificaciones de cada libro para que los libros comunes obtengan una clasificación más alta.

select similar.book_id, sum(ub_rank.rank) total_rank
from ub_rank
join ub similar on ub_rank.user_id = similar.user_id 
left join ub target on target.user_id = 1 and target.book_id = similar.book_id
where target.book_id is null
group by similar.book_id
order by total_rank desc;

+---------+------------+
| book_id | total_rank |
+---------+------------+
| D       |          3 |
| Z       |          2 |
| X       |          1 |
| Y       |          1 |
| Q       |          1 |
| W       |          1 |
+---------+------------+
6 rows in set (0.00 sec)

El libro Z apareció en dos listas de usuarios, por lo que se clasificó por encima de X, Y, Q, W, que solo apareció en la lista de un usuario. El libro D funcionó mejor porque apareció en la lista de user_id 2, que tenía 3 elementos en común con el objetivo user_id 1.