首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带有连接的MySQL相关标记

带有连接的MySQL相关标记
EN

Stack Overflow用户
提问于 2012-09-29 13:12:04
回答 1查看 657关注 0票数 0

因此,我有一个数据库,其中有一个名为article的表,还有一个名为文章标签的表。当用户查看一篇文章时,我想查询最多五篇标签与正在查看的文章相似的文章。下面是我的两个表:

代码语言:javascript
复制
CREATE TABLE `articles` (
  `article_id` int(15) NOT NULL AUTO_INCREMENT,
  `parent_id` int(15) NOT NULL,
  `author_id` int(15) NOT NULL,
  `title` text NOT NULL,
  `content` text NOT NULL,
  `date_posted` text NOT NULL,
  `views` int(15) NOT NULL,
  `preview` text NOT NULL,
  `status` tinyint(1) NOT NULL,
  `modified_date` text NOT NULL,
  PRIMARY KEY (`article_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1;

CREATE TABLE `article_tags` (
  `tag_id` int(15) NOT NULL AUTO_INCREMENT,
  `article_id` int(15) NOT NULL,
  `keyword` varchar(250) NOT NULL,
  PRIMARY KEY (`tag_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1;

我试着编写我自己的查询,但它们似乎从来都不起作用。我想在查询中使用joins,而不是使用CSV和LIKE。下面是我到目前为止得到的查询:

代码语言:javascript
复制
SELECT A2.article_id, count(A2.article_id) AS matches
FROM article_tags AS A1 JOIN article_tags ON (A1.keyword = A2.keyword AND 1.article_id != A2.article_id)
JOIN articles ON (A2.article_id = A.article_id) AS A
WHERE A1.article_id = 1
GROUP BY A2.article_id
ORDER BY matches DESC
LIMIT 5"

这是我更新的查询:

代码语言:javascript
复制
$query = "
            SELECT t2.article_id, count(t2.keyword) AS matches
            FROM article_tags t1
            JOIN article_tags t2 ON (t1.keyword = t2.keyword AND t1.article_id != t2.article_id)
            WHERE t1.article_id = ".$article_id."
            GROUP BY t2.article_id
            ORDER BY matches DESC
            LIMIT 5";

这是使用var_dump转储数组的结果

代码语言:javascript
复制
array
  0 => 
    array
      'article_id' => string '2' (length=1)
      'matches' => string '1' (length=1)

代码语言:javascript
复制
$query = "
            SELECT t2.article_id, count(t2.keyword) AS matches
            FROM article_tags t1
            JOIN article_tags t2 ON (t1.keyword = t2.keyword AND t1.article_id != t2.article_id)
            WHERE t1.article_id = ".$article_id."
            GROUP BY t2.article_id
            ORDER BY matches DESC
            LIMIT 5";

        if($query = $this->db->query($query)){

            if($query->num_rows() > 0){

                foreach($query->result_array() as $id => $article){

                    $articles[$id] = $this->fetch_article($article['article_id']);

                }

            } else {

                $articles = array();

            }

        } else {

            $articles = array();

        }

        return $articles;

    }

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-09-29 13:51:16

基本上你的想法是正确的-在article_tags表上建立一个自我连接。有一些你应该改进的地方:

  • 计数tag_id而不是article_id,因为您希望按相关性对文章进行排序,并且匹配标签的计数指示tag_id而不是keyword上的relevance.
  • Join。对非索引列的联接将是一个性能问题。出于性能原因,
  • 不在联接条件中使用!=。只需获取所有相关文章,并简单地删除最相关的文章,这应该是当前文章本身,出于性能原因,articles上的
  • Join不是必需的。您不需要文章本身;只需在获得5篇相关文章的ids后,在articles上进行简单的选择。

所以答案可能是这样的:

代码语言:javascript
复制
SELECT
    A2.article_id, count(A2.tag_id) AS matches
FROM 
    article_tags A1 
JOIN
    article_tags ON A1.tag_id=A2.tag_id
WHERE
    A1.article_id = 1
GROUP BY
    A2.article_id
ORDER BY
    matches DESC
LIMIT 6   -- instead of 5, because the first result would be the current article

你应该得到一个有6个ids的数组,只需删除第一个ids,然后执行SELECT操作(例如在python中):

代码语言:javascript
复制
article_ids = article_ids[1:]
articles = cursor.execute(
    "SELECT * FROM articles WHERE article_id IN (%s)" % ",".join(article_ids)
)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12650125

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档