获取2个单词匹配的MysQL行

时间:2010-12-17 13:15:49

标签: search mysql many-to-many

我正在尝试基于2个MySQL表构建一个简单的搜索。一个称为关键字(单词),另一个称为keyword2data(将单词绑定到数据源的地图)。

关键字包含id和关键字,而keywords2data包含keyword_id和data_id。

data_id it self是对第3个的引用,但在这种情况下是不重要的表。

我想要的是能够搜索“狗拉雪橇”这样的例子并获取所有绑定了这些关键字的data_id。

SELECT k2d.`data_id` , k2d.`keyword_id` 
FROM keywords2data as k2d, keywords as k 
WHERE k2d.`keyword_id` = k.`id` 
&& (k.`keyword` = 'dog' || k.`keyword` = 'sled') 
LIMIT 10

给我所有data_id,其中有狗或雪橇绑定它,两者都没有,这就是我想要的。

SELECT k2d.`data_id` , k2d.`keyword_id` 
FROM keywords2data as k2d, keywords as k 
WHERE k2d.`keyword_id` = k.`id` 
&& (k.`keyword` = 'dog' && k.`keyword` = 'sled') 
LIMIT 10

没有给我任何内容,因为在keywords2data中没有一行包含2个关键字。

这样做的正确方法是什么?

3 个答案:

答案 0 :(得分:3)

这样的东西
SELECT  k2d.`data_id` , 
        k2d.`keyword_id`  
FROM    keywords2data as k2d INNER JOIN
        keywords as k  ON k2d.`keyword_id` = k.`id` INNER JOIN
        keywords as k2  ON k2d.`keyword_id` = k2.`id`
WHERE   k.`keyword` = 'dog' 
AND     k2.`keyword` = 'sled'
LIMIT 10 

答案 1 :(得分:2)

这个怎么样?

SELECT k2d.`data_id`, 
       k2d.`keyword_id` 
FROM   keywords2data AS k2d 
       INNER JOIN keywords AS k 
         ON k2d.`keyword_id` = k.`id` 
WHERE  k.`keyword` IN ( 'dog', 'sled', 'rex' ) 
GROUP  BY k.keyword 
HAVING COUNT(*) = 3 

答案 2 :(得分:1)

可能,这个?

要扩展以匹配更多关键字,您只需在子查询中的OR语句中添加更多字词,然后再更改=2

这假定每个数据项使用kerywords2data一次且仅一次链接到关键字。

SELECT k2d.data_id
     , k2d.keyword_id

FROM keywords2data AS k2d
   , keywords AS k 

WHERE k2d.keyword_id = k.id
  AND (
       SELECT COUNT(*)
        FROM keywords2data AS sqk2d
           , keywords AS sqk 
        WHERE sqk2d.data_id = k2d.data_id
          AND sqk2d.keyword_id = sqk.id
          AND (sqk.keyword = 'dog' || sqk.keyword = 'sled')
       ) = 2

LIMIT 10

这是一个不会返回重复data_id的版本(根据评论),但也不会返回任何关键字:

SELECT k2d.data_id

FROM keywords2data AS k2d

WHERE (
       SELECT COUNT(*)
         FROM keywords2data AS sqk2d
            , keywords AS sqk 
        WHERE sqk2d.data_id = k2d.data_id
          AND sqk2d.keyword_id = sqk.id
          AND (sqk.keyword = 'dog' || sqk.keyword = 'sled')
      ) = 2

LIMIT 10