Masz pytanie dotyczące Jak obliczyć, które miasta są najbliżej spokrewnione? Na przykład. Patrząc na miasto 1 (Paryż), wyniki powinny wyglądać następująco:Londyn (2), Nowy Jork (3) i na podstawie dostarczonego zestawu danych jest tylko jedna rzecz do powiązania to znaczy wspólne tagi między miastami, więc miasta, które dzielą te wspólne tagi będą najbliższe z poniższych to podzapytanie, które znajduje miasta (inne niż te, które są dostarczane do znaleźć najbliższe miasta), które mają wspólne tagi
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 )
Praca
Zakładam, że wprowadzisz jeden z identyfikatorów miasta lub nazwy, aby znaleźć najbliższe w moim przypadku „Paryż” ma ten identyfikator
SELECT tag_id FROM `cities_tags` WHERE city_id=1
Znajdzie wszystkie tagi id, które ma Paryż
SELECT city_id FROM `cities_tags` WHERE tag_id IN (
SELECT tag_id FROM `cities_tags` WHERE city_id=1) AND city_id !=1 )
Pobrane zostaną wszystkie miasta z wyjątkiem Paryża, który ma te same znaczniki, co Paryż
Oto Twoje Skrzypce
Czytając o podobieństwach/indeksie Jaccarda znalazłem kilka rzeczy do zrozumienia, czym właściwie są terminy, weźmy ten przykład, mamy dwa zestawy A i B
Teraz przejdź do swojego scenariusza
Oto zapytanie do tej pory, które oblicza idealny indeks jaccarda, który można zobaczyć w poniższym przykładzie skrzypiec
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
W powyższym zapytaniu wyprowadziłem zestaw wyników do dwóch podselekcji, aby uzyskać moje niestandardowe obliczone aliasy
Możesz dodać filtr w powyższym zapytaniu, aby nie obliczać podobieństwa do siebie
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
Wynik pokazuje, że Paryż jest blisko spokrewniony z Londynem, a następnie z Nowym Jorkiem