基于mysql中的加权标签对文章进行排序

时间:2013-06-25 08:49:17

标签: mysql sorting

我使用以下结构:

Table Article:
id
title

Table ArticleTags:
id
articleid
tagid

Table Tags:
id
tagname
preferenece [0-5]

现在我需要根据多个标签对文章进行排序。是否可以使用mysql单一查询

示例:

article A is tagged by following tags and preference
pc 2
mobile 3
tech 1

article B is tagged by following tags and preference
tech 3
php 2
grails 4
mobile 2

现在,如果我想按标签排序 - 移动和技术,文章B将排名第一。如果我只按移动排序,则文章A将排名第一。

3 个答案:

答案 0 :(得分:1)

表的关系不太清楚,我在考虑这样的关系:

Article Table (id) <= (articleid) ArticleTags Table (tagid) => (id) Tags Table

根据您给定的条件,看起来SUM的{​​{1}}用于对输出进行排序。

所以我最终得到了这个问题:

preference

还不清楚SELECT A.title , SUM(T.preference) AS preferenceSum FROM Tags T INNER JOIN ArticleTags AT ON T.tagid = T.id INNER JOIN Article A ON A.id = AT.articleid WHERE T.tagname IN ('mobile', 'tech') GROUP BY A.id ORDER BY preferenceSum DESC; tags的不同之处。根据您的问题,preferencemobile存在不同的tech。或者我们在这里缺少一些表格。

答案 1 :(得分:1)

如果您希望按最高标签偏好排序,则可以这样: -

SELECT Article.id, Article.title, Sub1.MaxPreference
FROM Article
INNER JOIN
(
    SELECT Article.id, MAX(Tags.preference) AS MaxPreference
    FROM Article
    INNER JOIN ArticleTags ON Article.id = ArticleTags.articleid
    INNER JOIN Tags ON ArticleTags.tagid = Tags.id
    GROUP BY Article.id
) Sub1
ON Article.id = Sub1.id
ORDER BY Sub1.MaxPreference DESC

将其限制为仅考虑几个标签: -

SELECT Article.id, Article.title, Sub1.MaxPreference
FROM Article
LEFT OUTER JOIN
(
    SELECT Article.id, MAX(Tags.preference) AS MaxPreference
    FROM Article
    INNER JOIN ArticleTags ON Article.id = ArticleTags.articleid
    INNER JOIN Tags ON ArticleTags.tagid = Tags.id
    WHERE Tags.tagname IN ('mobile','tech')
    GROUP BY Article.id
) Sub1
ON Article.id = Sub1.id
ORDER BY Sub1.MaxPreference DESC

如果您希望按照首选项的总和对它们进行排序,则可以这样: -

SELECT Article.id, Article.title, Sub1.SumPreference
FROM Article
INNER JOIN
(
    SELECT Article.id, SUM(Tags.preference) AS SumPreference
    FROM Article
    INNER JOIN ArticleTags ON Article.id = ArticleTags.articleid
    INNER JOIN Tags ON ArticleTags.tagid = Tags.id
    GROUP BY Article.id
) Sub1
ON Article.id = Sub1.id
ORDER BY Sub1.SumPreference DESC

答案 2 :(得分:1)

由于标签对于不同的文章具有不同的权重IMHO,因此在articletags表而不是tags表中具有偏好(权重)列是很自然的。否则,您将使用相同名称但权重不同的标签中的多个条目。

因此我建议您更改架构

CREATE TABLE articletags
  (`id` int, `articleid` int, `tagid` int, `preference` int);
CREATE TABLE tags
  (`id` int, `tagname` varchar(32));

现在所有其他规则来获得每篇文章的权重总和并应用订单都是相同的

SELECT a.* 
  FROM article a JOIN
(
  SELECT articleid, SUM(at.preference) total_preference
    FROM articletags at JOIN tags t
      ON at.tagid = t.id
   WHERE t.tagname IN ('mobile', 'tech')
   GROUP BY articleid
) q ON a.id = q.articleid
 ORDER BY q.total_preference DESC

这是 SQLFiddle 演示