Mysql
 sql >> Baza danych >  >> RDS >> Mysql

MySQL / PHP:Znajdź podobne / powiązane elementy według tagów / taksonomii

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

Jaccard podobieństwo Fiddle



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. jak uniknąć impasu w mysql

  2. Jak uzyskać dostęp do MySQL za pomocą głównego użytkownika MySQL?

  3. wstaw tablicę php do mySql

  4. Yii2:automatyczne wypełnianie pól na podstawie innego pola z powiązanej tabeli

  5. Pasek postępu Bootstrap z danymi MYSQL przy użyciu PHP?