Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

MySQL / PHP:Temukan item serupa / terkait dengan tag / taksonomi

Anda bertanya tentang Bagaimana cara menghitung kota mana yang paling dekat hubungannya? Sebagai contoh. Jika saya melihat kota 1 (Paris), hasilnya seharusnya:London (2), New York (3) dan berdasarkan kumpulan data yang Anda berikan, hanya ada satu hal yang terkait yaitu tag umum di antara kota-kota sehingga kota-kota yang berbagi tag umum akan menjadi yang terdekat di bawah ini adalah subquery yang menemukan kota-kota tersebut (selain yang disediakan untuk temukan kota terdekatnya) yang berbagi tag umum

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 )

Bekerja

Saya berasumsi Anda akan memasukkan salah satu id kota atau nama untuk menemukan yang terdekat dalam kasus saya "Paris" memiliki id satu

 SELECT tag_id FROM `cities_tags` WHERE city_id=1

Ini akan menemukan semua id tag yang dimiliki paris

SELECT city_id FROM `cities_tags` WHERE tag_id IN (
    SELECT tag_id FROM `cities_tags` WHERE city_id=1) AND city_id !=1 )

Ini akan mengambil semua kota kecuali paris yang memiliki beberapa tag yang sama dengan yang juga dimiliki paris

Ini Fiddle Anda

Saat membaca tentang kesamaan/indeks Jaccard menemukan beberapa hal untuk dipahami tentang apa sebenarnya istilahnya, mari kita ambil contoh ini, kami memiliki dua set A &B

Sekarang pindah ke skenario Anda

Berikut adalah kueri sejauh ini yang menghitung indeks jaccard sempurna, Anda dapat melihat contoh biola di bawah ini

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 

Dalam kueri di atas, saya telah mendapatkan hasil yang disetel ke dua subpilihan untuk mendapatkan alias yang dihitung khusus

Anda dapat menambahkan filter dalam kueri di atas untuk tidak menghitung kesamaan dengan dirinya sendiri

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

Jadi hasilnya menunjukkan Paris terkait erat dengan London dan kemudian terkait dengan New York

Fiddle Kesamaan Jaccard



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PHP MySQL LOAD DATA INFILE Bantuan

  2. Cara mendapatkan semua baris yang berisi karakter selain [a-zA-Z] di MySQL

  3. Bisakah saya menyiapkan replikasi basis data pola bintang yang difilter?

  4. Apa yang dimaksud dengan karakter \x1a

  5. Versi Django MySQLdb tidak cocok dengan _mysql versi Ubuntu