sql >> Database teknologi >  >> RDS >> Mysql

MySQL / PHP:Find lignende / relaterede emner efter tag / taksonomi

Dit spørgsmål om Hvordan beregner jeg, hvilken by der er tættest beslægtet? For eksempel. Hvis jeg kiggede på by 1 (Paris), skulle resultaterne være:London (2), New York (3) og baseret på dit angivne datasæt er der kun én ting at forholde sig til, nemlig de fælles tags mellem byerne, så de byer, der deler de fælles tags, ville være den nærmeste nedenfor, er underforespørgslen, der finder byerne (ud over det, der er givet til finde dens nærmeste byer), der deler de fælles tags

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 )

Arbejder

Jeg antager, at du vil indtaste en af ​​byens id eller navn for at finde deres nærmeste i mit tilfælde "Paris" har id en

 SELECT tag_id FROM `cities_tags` WHERE city_id=1

Den vil finde alle de tags-id'er, som paris har så

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 vil hente alle byerne undtagen Paris, der har de samme tags, som Paris også har

Her er din violin

Mens du læser om Jaccard-ligheden/indekset fundet nogle ting at forstå om, hvad udtrykket faktisk er, lad os tage dette eksempel, vi har to sæt A &B

Gå nu mod dit scenarie

Her er forespørgslen indtil videre, som beregner det perfekte jaccard-indeks, du kan se nedenstående spille-eksempel

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 ovenstående forespørgsel har jeg udledt resultatet sat til to undervalg for at få mine tilpassede beregnede aliaser

Du kan tilføje filteret i ovenstående forespørgsel for ikke at beregne ligheden med sig selv

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 viser, at Paris er tæt knyttet til London og derefter relateret til New York

Jaccard Similarity Fiddle



  1. Bestem rang baseret på flere kolonner i MySQL

  2. Hvordan definerer man en pl sql-funktion med dynamiske returtyper i Oracle?

  3. Kom godt i gang med SQL Server 2017 på Linux i Azure-portalen

  4. Brug af PHP-MySQL-vedvarende forbindelser til at køre WordPress-blog