簡體   English   中英

MySQL與聯接相關的標簽

[英]MySQL Related Tags With Joins

因此,我有一個數據庫,其中包含一個名為artcles的表,以及一個名為商品標簽的表。 當用戶查看一篇文章時,我想查詢最多五篇標簽與所查看文章相似的文章。 這是我的兩張桌子:

 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; 

我嘗試編寫自己的查詢,但是它們似乎從未起作用。 我想在查詢中使用聯接,而不是使用CSV和LIKE。 這是我到目前為止的查詢:

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"

這是我更新的查詢:

 $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轉儲數組的結果

 array 0 => array 'article_id' => string '2' (length=1) 'matches' => string '1' (length=1) 

 $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; } 

基本上,您的想法是正確的-在article_tags表上進行自我聯接。 有一些應該改進的地方:

  • COUNT個tag_id而不是article_id ,因為您想按相關性對文章進行排序,並且匹配標簽的數量表示相關性。
  • 加入tag_id而不是keyword 在非索引列上加入將是一個性能問題。
  • 出於性能原因,請勿在JOIN條件下使用!= 只需獲取所有相關文章,然后刪除最相關的文章,那應該是當前文章本身
  • 由於性能原因,不需要加入articles 您不需要這些文章本身。 在獲得5條相關文章的ID之后,只需對articles進行簡單的SELECT。

因此答案可能是這樣的:

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個id的數組,然后刪除第一個id,然后執行SELECT(例如在python中):

article_ids = article_ids[1:]
articles = cursor.execute(
    "SELECT * FROM articles WHERE article_id IN (%s)" % ",".join(article_ids)
)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM