Mysql 查找对另一列中的值进行迭代的最大计数

Mysql 查找对另一列中的值进行迭代的最大计数,mysql,sql,Mysql,Sql,正在寻找有关MySQL查询的帮助 我有一个表,看起来像这样,但它会继续显示更多具有许多不同id值和年份的行: from_museum_id to_museum_id piece_id year 1 4 4 2010 1 4 5 2010 1 4 32 2010

正在寻找有关MySQL查询的帮助

我有一个表,看起来像这样,但它会继续显示更多具有许多不同id值和年份的行:

from_museum_id  to_museum_id    piece_id    year
1               4               4           2010
1               4               5           2010
1               4               32          2010
1               4               18          2013
1               4               18          2013
1               4               18          2014
1               4               18          2015
2               4               12          2015
2               4               7           2015
2               4               6           2015
2               4               33          2015
2               4               12          2017
2               4               6           2017
我有一个为我试图找到的相关结果集编写的查询:

SELECT m.from_museum_id, m.year, COUNT(*) AS number_loaned
FROM museum_loan m
GROUP BY m.from_museum_id, m.year
HAVING COUNT(*) > 1;
这给了我一个结果集:

from_museum_id  year    number_loaned
1               2013    2
1               2010    3
2               2017    2   
2               2015    4
但我的问题是,我只需要贷款数量最多的年份如下:

from_museum_id  year    number_loaned
1               2010    3
2               2015    4
我尝试在HAVING语句中实现一个子查询,该语句试图将COUNT*与它的MAX进行比较,但没有效果。我一直只得到贷款数量最大的单行,这导致:

from_museum_id  year    number_loaned
2               2015    4
这张桌子很大,有很多可以考虑的,所以按顺序和限制的任何把戏对我来说都不行。

我已经搜索了一个小时,但可能我的SQL新手技能让我无法理解如何解决这个问题,如果它是在Python/R中,那就太容易了!,尽管可能有一个答案适用于这个案例


非常感谢您的建议。

如果您使用的是MYSQL V8及以上版本,您可以尝试以下方法:

WITH temp 
     AS (SELECT m.from_museum_id, 
                m.year, 
                Count(from_museum_id) AS number_loaned 
         FROM   museum_loan m 
         GROUP  BY m.from_museum_id, 
                   m.year 
         HAVING Count(from_museum_id) > 0) 
SELECT from_museum_id, 
       year, 
       number_loaned 
FROM   temp t1 
       INNER JOIN (SELECT from_museum_id, 
                          Max(number_loaned) AS number_loaned 
                   FROM   temp 
                   GROUP  BY from_museum_id) t2 
               ON t1.from_museum_id = t2.from_museum_id 
                  AND t1.number_loaned = t2.number_loaned; 

尝试使用原始查询的结果作为派生表进行查询:

选择m_id,年份,从中借出的最大数量选择m.FROM_museum_id作为m_id,m.year作为年份,m.FROM_museum_id将*作为从博物馆贷款m组借出的数量,m.year具有*大于1的计数
按m_id分组

您可以模拟密集秩函数

SELECT m.from_museum_id, m.year, COUNT(*) AS number_loaned,
        if(m.from_museum_id <> @p, @rn:=1,@rn:=@rn+1) rn,
         @p:=m.from_museum_id p
FROM t m
cross join (select @rn:=0,@p:=0) r
GROUP BY m.from_museum_id, m.year
HAVING COUNT(*) > 1 and rn = 1
order by m.from_museum_id, count(*) desc

+----------------+------+---------------+------+------+
| from_museum_id | year | number_loaned | rn   | p    |
+----------------+------+---------------+------+------+
|              1 | 2010 |             3 |    1 |    1 |
|              2 | 2015 |             4 |    1 |    2 |
+----------------+------+---------------+------+------+
2 rows in set (0.00 sec)

您要查找的查询是:

SELECT m.from_museum_id, m.year,
       COUNT(*) AS number_loaned
FROM museum_loan m
GROUP BY m.from_museum_id, m.year
HAVING m.year = (SELECT m2.year
                 FROM museum_loan m2
                 WHERE m2.from_museum_id = m.from_museum_id
                 GROUP BY m2.year
                 ORDER BY COUNT(*) DESC
                 LIMIT 1
                );
您还可以使用GROUP\u CONCAT/SUBSTRING\u INDEX hack:


这应该可以使用子查询/派生表来解决。看,我试过类似的方法,但它再次向我展示了一排博物馆和年份的借出数量最多,而不是每个博物馆和年份的借出数量最多。我尝试将此添加到HAVING子句中:AND COUNT*=SELECT COUNT*中选择MAXcnt作为museum\u loan m GROUP中的cnt,由m.FROM\u museum\u id,m.year sub;您使用什么MySQL版本?选择版本,您还可以发布表结构显示CREATE table museum\u如果您缩进或格式化SQL查询,您会看到它,那么您可以为派生表添加别名。SQL应该是可读的、可理解的和可维护的,而SQL一行程序则不是这样。另外,您的查询不是ANSI SQL,并且误用了MysQL的GROUP BY功能,这意味着它将在MysQL服务器上失败,并且只有_FULL_GROUP_BY SQL_模式。。。请参阅演示,您在HAVING语句中忘记了COUNT*>1,但这是一个简单的添加,除此之外,这些查询非常优雅简洁+1.
SELECT my.from_museum_id,
       SUBSTRING_INDEX(GROUP_CONCAT(year ORDER BY number_loaned DESC) as year,
       MAX(number_loaned) as number_loaned
FROM (SELECT m.from_museum_id, m.year,
             COUNT(*) AS number_loaned
      FROM museum_loan m
      GROUP BY m.from_museum_id, m.year
     ) my
GROUP BY my.from_museum_id;