sql >> Databasteknik >  >> RDS >> Mysql

MySQL / PHP:Hitta liknande / relaterade objekt efter tagg / taxonomi

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

Jaccard Similarity Fiddle



  1. Oracle DB citat kolumnnamn

  2. Kan jag konfigurera Aurora DB max identifierarlängd? Hur?

  3. Hur får man lediga datum med reservationer?

  4. Hur man fixar fel:MySQL stängs av oväntat på Xampp på grund av plugin 'Aria'