Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 如何处理内部联接和组数据,同时将过去两个月的每个相关条目限制为1?_Mysql - Fatal编程技术网

Mysql 如何处理内部联接和组数据,同时将过去两个月的每个相关条目限制为1?

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

我想从一个表中获得所有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      | 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ć请参阅我的编辑。第二个查询将给出每个月的最后评分,而不是平均值。更新的演示包含两个查询,因此您可以比较结果。