如何做内部连接和组数据,同时限制相关的条目为1为每两个月?

irtuqstp  于 2021-06-17  发布在  Mysql
关注(0)|答案(1)|浏览(185)

我想得到一个从一个表中的所有网址连同两个在第二个表中的每个网址评级列表。问题是,一个评级应该来自当月(如果存在),另一个评级应该来自上月(如果存在)。用mysql可以实现吗?每个url行的两个分级都应分组到一个单元格中。
每个月用一次或多次的新值填充数据库。
表结构和样本数据:

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

这只是一个查询的开始,我不知道我该如何限制2个评级为每个网址如上所述?

SELECT 
    urls.id, 
    urls.url, 
    ratings.rating

FROM urls

INNER JOIN  ratings 
ON urls.id = ratings.url_id
3qpi33ja

3qpi33ja1#

可以使用条件聚合来获得所需的结果。我假设您希望使用每个月的平均评级进行比较。

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

更新
只使用每个月的最后一次评分(如评论中所要求的)要复杂一些。两个就可以了 JOIN 到包含上个月和本月最后评级的表:

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

更新了dbfiddle的演示

相关问题