Du frågar om Hur beräknar jag vilken som är den närmast besläktade staden? Till exempel. Om jag tittade på stad 1 (Paris) borde resultaten bli:London (2), New York (3) och baserat på din tillhandahållna datamängd finns det bara en sak att relatera, det är de gemensamma taggarna mellan städerna, så städerna som delar de gemensamma taggarna skulle vara den närmaste nedan är underfrågan som hittar städerna (annat än den som tillhandahålls till hitta sina närmaste städer) som delar de vanliga taggarna
SELECT * FROM `cities` WHERE id IN (
SELECT city_id FROM `cities_tags` WHERE tag_id IN (
SELECT tag_id FROM `cities_tags` WHERE city_id=1) AND city_id !=1 )
Fungerar
Jag antar att du kommer att ange ett av stadens id eller namn för att hitta deras närmaste i mitt fall "Paris" har id ett
SELECT tag_id FROM `cities_tags` WHERE city_id=1
Den kommer att hitta alla taggar-id som paris har då
SELECT city_id FROM `cities_tags` WHERE tag_id IN (
SELECT tag_id FROM `cities_tags` WHERE city_id=1) AND city_id !=1 )
Det kommer att hämta alla städer utom paris som har samma taggar som paris också har
Här är din Fiol
När du läser om Jaccard-likheten/indexet hittade några saker att förstå om vad termerna faktiskt är, låt oss ta det här exemplet, vi har två uppsättningar A &B
Gå nu mot ditt scenario
Här är frågan hittills som beräknar det perfekta jaccard-indexet. Du kan se nedan fiolexempel
SELECT a.*,
( (CASE WHEN a.`intersect` =0 THEN a.`union` ELSE a.`intersect` END ) /a.`union`) AS jaccard_index
FROM (
SELECT q.* ,(q.sets + q.parisset) AS `union` ,
(q.sets - q.parisset) AS `intersect`
FROM (
SELECT cities.`id`, cities.`name` , GROUP_CONCAT(tag_id SEPARATOR ',') sets ,
(SELECT GROUP_CONCAT(tag_id SEPARATOR ',') FROM `cities_tags` WHERE city_id= 1)AS parisset
FROM `cities_tags`
LEFT JOIN `cities` ON (cities_tags.`city_id` = cities.`id`)
GROUP BY city_id ) q
) a ORDER BY jaccard_index DESC
I ovanstående fråga har jag härlett resultatet till två underval för att få mina anpassade beräknade alias
Du kan lägga till filtret i ovanstående fråga för att inte beräkna likheten med sig själv
SELECT a.*,
( (CASE WHEN a.`intersect` =0 THEN a.`union` ELSE a.`intersect` END ) /a.`union`) AS jaccard_index
FROM (
SELECT q.* ,(q.sets + q.parisset) AS `union` ,
(q.sets - q.parisset) AS `intersect`
FROM (
SELECT cities.`id`, cities.`name` , GROUP_CONCAT(tag_id SEPARATOR ',') sets ,
(SELECT GROUP_CONCAT(tag_id SEPARATOR ',') FROM `cities_tags` WHERE city_id= 1)AS parisset
FROM `cities_tags`
LEFT JOIN `cities` ON (cities_tags.`city_id` = cities.`id`) WHERE cities.`id` !=1
GROUP BY city_id ) q
) a ORDER BY jaccard_index DESC
Så resultatet visar att Paris är nära besläktat med London och sedan relaterat till New York