我使用以下结构:
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将排名第一。
答案 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
的不同之处。根据您的问题,preference
和mobile
存在不同的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 演示