Mysql 如何处理内部联接和组数据,同时将过去两个月的每个相关条目限制为1?
我想从一个表中获得所有URL的列表,以及第二个表中每个URL的两个评级。问题是,如果存在,一个评级应该来自当月,如果存在,另一个评级也应该来自上月。用MySQL可以实现吗?每个URL行的两个评级都应分组到一个单元格中 每个月将用新值填充数据库一次或多次 表结构和样本数据:Mysql 如何处理内部联接和组数据,同时将过去两个月的每个相关条目限制为1?,mysql,Mysql,我想从一个表中获得所有URL的列表,以及第二个表中每个URL的两个评级。问题是,如果存在,一个评级应该来自当月,如果存在,另一个评级也应该来自上月。用MySQL可以实现吗?每个URL行的两个评级都应分组到一个单元格中 每个月将用新值填充数据库一次或多次 表结构和样本数据: urls id | url 1 | google.com 2 | apple.com 3 | bing.com ratings id | rating | url_id | created_at 1 | 10
urls
id | url
1 | google.com
2 | apple.com
3 | bing.com
ratings
id | rating | url_id | created_at
1 | 10 | 1 | 2018-10-10
2 | 8 | 2 | 2018-10-10
3 | 11 | 1 | 2018-11-10
4 | 5 | 2 | 2018-11-10
5 | 6 | 3 | 2018-11-25
最后,我的目标是显示一个简单的URL表,并比较每个月的评级
url | previous rating | current rating
google.com | 10 | 11 (rating has increased)
apple.com | 8 | 5 (rating has decreased)
bing.com | - | 6
这只是一个查询的开始,我不知道如何限制每个url的2个评级,如上所述
SELECT
urls.id,
urls.url,
ratings.rating
FROM urls
INNER JOIN ratings
ON urls.id = ratings.url_id
您可以使用条件聚合来获得所需的结果。我假设您希望使用每个月的平均评级进行比较
SELECT u.url,
AVG(CASE WHEN MONTH(r.created_at) = MONTH(CURDATE() - INTERVAL 1 MONTH)
AND YEAR(r.created_at) = YEAR(CURDATE() - INTERVAL 1 MONTH) THEN rating END) AS `previous rating`,
AVG(CASE WHEN MONTH(r.created_at) = MONTH(CURDATE())
AND YEAR(r.created_at) = YEAR(CURDATE()) THEN rating END) AS `current rating`
FROM urls u
LEFT JOIN ratings r
ON r.url_id = u.id
GROUP BY u.url
ORDER BY `current rating` DESC
输出:
url previous rating current rating
google.com 10.0000 11.0000
bing.com 6.0000
apple.com 8.0000 5.0000
更新
按照评论中的要求,只使用每个月的最后一次评分,这有点复杂。可以通过两个表连接来完成此操作,这些表包含上一个月和当前月份的最后评级:
SELECT u.url,
pr.rating AS `previous rating`,
cr.rating AS `current rating`
FROM urls u
LEFT JOIN (SELECT url_id, rating
FROM ratings r1
WHERE created_at = (SELECT MAX(created_at)
FROM ratings r2
WHERE r2.url_id = r1.url_id AND
MONTH(created_at) = MONTH(CURDATE() - INTERVAL 1 MONTH) AND
YEAR(created_at) = YEAR(CURDATE() - INTERVAL 1 MONTH)
)
) pr ON pr.url_id = u.id
LEFT JOIN (SELECT url_id, rating
FROM ratings r1
WHERE created_at = (SELECT MAX(created_at)
FROM ratings r2
WHERE r2.url_id = r1.url_id
)
) cr ON cr.url_id = u.id
ORDER BY `current rating` DESC
提示,连接到评级两次,内部连接评级\u上一次。。。内部连接评级_当前…非常感谢,我不需要平均值,只需要当前和上月的单个最后值。Hm我如何删除平均值?:@IvanTopić请参阅我的编辑。第二个查询将给出每个月的最后评分,而不是平均值。更新的演示包含两个查询,因此您可以比较结果。