sql >> Database >  >> RDS >> Mysql

MySQL / PHP:zoek vergelijkbare / gerelateerde items op tag / taxonomie

Je vraag over Hoe bereken ik welke stad het meest verwant is? Bijvoorbeeld. Als ik naar stad 1 (Parijs) zou kijken, zouden de resultaten moeten zijn:Londen (2), New York (3) en op basis van uw verstrekte gegevensset is er maar één ding om te relateren, namelijk de gemeenschappelijke tags tussen de steden, dus de steden die de gemeenschappelijke tags delen, zijn de dichtstbijzijnde hieronder is de subquery die de steden vindt (anders dan die wordt verstrekt aan vind de dichtstbijzijnde steden) die de gemeenschappelijke tags delen

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 )

Werken

Ik neem aan dat je een van de stads-ID's of namen invoert om de dichtstbijzijnde te vinden in mijn geval dat "Parijs" de ID heeft

 SELECT tag_id FROM `cities_tags` WHERE city_id=1

Het zal alle tags id vinden die parijs dan heeft

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

Het haalt alle steden op behalve parijs die dezelfde tags hebben die parijs ook heeft

Hier is je Fiddle

Tijdens het lezen over de Jaccard-overeenkomst/index we hebben wat dingen gevonden om te begrijpen wat de termen eigenlijk zijn, laten we dit voorbeeld nemen, we hebben twee sets A &B

Ga nu naar uw scenario

Hier is de zoekopdracht tot nu toe die de perfecte jaccard-index berekent, je kunt het onderstaande voorbeeld van de viool zien

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 

In bovenstaande query heb ik de ik heb de resultaatset afgeleid van twee subselects om mijn aangepaste berekende aliassen te krijgen

U kunt het filter in bovenstaande zoekopdracht toevoegen om de overeenkomst met zichzelf niet te berekenen

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

Dus het resultaat laat zien dat Parijs nauw verwant is aan Londen en vervolgens verwant is aan New York

Jaccard Gelijkenis Fiddle



  1. Laravel 4 kan geen hele RAW-query's uitvoeren

  2. IF-statement in MySQL gebruiken om te updaten of in te voegen zonder Stored Procedure?

  3. MySQL-openingstijden

  4. Vreemd Mysql-probleem bij invoegen