简体   繁体   English

如何根据MySQL中的相关性将两个表的行相互映射?

[英]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. 我有以下我的数据库表: courses (体育类的整个数据), coursedata (含复印件courses.titlecourses.description -需要FULLTEXT索引/搜索的相关性), sports (体育的列表),并courses_sports (关联表)-参见下文。

Now I want to map the courses relevance based to the sports and to fill courses_sports with this data automatically. 现在,我想映射与运动相关的课程,并自动用此数据填充courses_sports It needs two steps. 它需要两个步骤。

  1. Collect the data with an apporiate SELECT . 使用适当的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 错误代码:1210

Incorrect arguments to AGAINST 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. 您还忘记了MATCH之前的WHERE语句。

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. 而且,由于您同时需要coursedata.title和coursedata.description,因此可以将它们加入比赛。

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. 最后,您不能在sports.title中使用该字段,因为这将意味着所有要比较的体育标题都可以遍历并将其值放入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 可能还可以使用BOOLEAN模式,因为如果您有50%或以上的AGAINST匹配项,则该模式将不起作用

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. 我有一个SQL Fiddle示例,但只有两个表,即Coursedata和sports,并在两个表之间添加了一个公共字段。

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. 也许您可以将所有结果都结合起来。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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