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