简体   繁体   中英

How to map rows of two tables to each other based on the relevance in MySQL?

I have following tables in my database: courses (whole data of sports classes), coursedata (with copies of courses.title and courses.description -- needed for FULLTEXT index / relevance search), sports (list of sports), and courses_sports (association table) -- see below.

Now I want to map the courses relevance based to the sports and to fill courses_sports with this data automatically. It needs two steps.

  1. Collect the data with an apporiate SELECT .

  2. Write the data to the association table.

This post is about the first step. I have some troubles writing the query. What I've tried:

SELECT
    courses.id,
    sports.id
FROM
    courses
JOIN
    coursedata ON coursedata.id = courses.coursedata_id
JOIN
    sports ON MATCH (coursedata.title) AGAINST (sports.title) > 0
-- The test with
-- sports ON MATCH (coursedata.title) AGAINST ('Basketball') > 0
-- works.

This query is not working:

Error Code: 1210

Incorrect arguments to AGAINST

How to implement this mapping correctly?


Additional information: relevant tables

courses

Field               Type             Key    
------------------  ---------------  ------ 
id                  int(11)          PRI             
title               varchar(100)                     
description         varchar(1000)                    
coursedata_id       int(11)          UNI     
...

coursedata

Field        Type           Collation        Null    Key     
-----------  -------------  ---------------  ------  ------  
id           int(11)        (NULL)           NO      PRI     
title        varchar(100)   utf8_general_ci  YES     MUL     
description  varchar(1000)  utf8_general_ci  YES     MUL     

CREATE TABLE `coursedata` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(100) DEFAULT NULL,
  `description` varchar(1000) DEFAULT NULL,
  PRIMARY KEY (`id`),
  FULLTEXT KEY `searchcoursetitle` (`title`),
  FULLTEXT KEY `searchcoursedescription` (`description`)
) ENGINE=MyISAM AUTO_INCREMENT=5208 DEFAULT CHARSET=utf8

sports

Field     Type                   Collation        Null    Key     
--------  ---------------------  ---------------  ------  ------  
id        int(11)                (NULL)           NO      PRI     
title     varchar(50)            utf8_general_ci  NO              
category  varchar(50)            utf8_general_ci  YES             
type      enum('sport','dance')  utf8_general_ci  YES             

courses_sports

Field      Type     Collation  Null    Key     
---------  -------  ---------  ------  ------  
course_id  int(11)  (NULL)     NO      PRI     
sport_id   int(11)  (NULL)     NO      PRI     

You forgot to provide the common field between sports and courses which in this case you join. You also forgot the WHERE statement before the MATCH.

JOIN
    sports ON MATCH (coursedata.title) AGAINST (sports.title) > 0 AND
    sports ON MATCH (coursedata.description) AGAINST (sports.title) > 0

So, it should be like this:

JOIN
    sports ON (course.commonid = sports.commonid) WHERE MATCH 

And since you want both the coursedata.title and coursedata.description you could join them in match.

JOIN
    sports ON (course.commonid = sports.commonid) WHERE MATCH(coursedata.title, coursedata.description)

and finally You could not use the field in sports.title because that would mean all the sports title to be compare AGAINST you could probably traverse and put the value inside the AGAINST.

JOIN
    sports ON (course.commonid = sports.commonid) WHERE MATCH(coursedata.title, coursedata.description) AGAINST('Martial')

and probably you could also use BOOLEAN mode because it will not work if you have 50% or more AGAINST matches

JOIN
    sports ON (course.commonid = sports.commonid) WHERE MATCH(coursedata.title, coursedata.description) AGAINST('Martial' IN BOOLEAN MODE)

I have an SQL Fiddle sample but with only two tables, namely, coursedata and sports and added a common field between the two.

AND finally probably you don't have to JOIN sports table but instead traverse on it and then match against? And probably you could just UNION ALL the results.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM