Mysql
 sql >> база данни >  >> RDS >> Mysql

MySQL / PHP:Намерете подобни / свързани елементи по етикет / таксономия

Питате за Как да изчисля кои са най-тясно свързаните градове? Например. Ако гледах град 1 (Париж), резултатите трябва да са:Лондон (2), Ню Йорк (3) и въз основа на предоставения от вас набор от данни има само едно нещо, което да се свърже, а това са общите тагове между градовете, така че градовете, които споделят общите тагове, биха били най-близкият по-долу е подзаявката, която намира градовете (освен предоставената на намери най-близките му градове), който споделя общите тагове

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 )

Работи

Предполагам, че ще въведете един от идентификаторите на града или името, за да намерите най-близкия им в моя случай „Париж“ има идентификатора

 SELECT tag_id FROM `cities_tags` WHERE city_id=1

Ще намери всички идентификатори на тагове, които 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 )

Ще извлече всички градове с изключение на париж, който има същите тагове, които има и париж

Ето го вашият Fiddle

Докато четете за приликата/индекса на Jaccard намерих някои неща, за да разберем какво всъщност са условията, нека вземем този пример, имаме два набора A &B

Сега преминете към вашия сценарий

Ето заявката досега, която изчислява перфектния индекс на jaccard, можете да видите примера за цигулка по-долу

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 

В горната заявка имам, че съм извлякъл набора от резултати до две подизбори, за да получа моите персонализирани изчислени псевдоними

Можете да добавите филтъра в горната заявка, за да не изчислявате сходството със себе си

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

Така че резултатът показва, че Париж е тясно свързан с Лондон и след това с Ню Йорк

Jaccard Similarity 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. ImportError:Няма модул с име mysql.connector, използващ Python2

  2. Преобразуване на два фрейма от данни в spark sql

  3. Как да използвате групиране по и самостоятелно присъединяване, за да върнете минимални, максимални, отворени и затворени дневни резултати от цената?

  4. MySQL код за конвертиране на дата и час в Excel

  5. не може да пусне външен ключ в mySQL