查找另一列中的值迭代的最大计数

时间:2018-07-08 10:13:14

标签: mysql sql

寻求有关MySQL查询的帮助。

我有一个看起来像这样的表(但它会继续使用具有不同ID值和年份的更多行):

.partition(/(?<=[aeiou])/i).reject(&:empty?)

我有一个查询要查询相关结果集:

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

我尝试在HAVING语句中实现子查询,该语句试图将COUNT(*)与其MAX进行比较无济于事。我一直只得到借出的数字最大的单行,结果是:

from_museum_id  year    number_loaned
1               2010    3
2               2015    4

此表很大,要考虑的from_museum_id太多,因此使用ORDER BY和LIMIT的任何技巧都不会帮我实现。

我已经搜索了一个小时,但是也许我的SQL新手使我无法理解如何解决此问题(如果仅在Python / R中,那将非常容易!),即使可能存在在这种情况下可以在某个地方回答。

我非常感谢您的建议。

4 个答案:

答案 0 :(得分:1)

您要查找的查询是:

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_CONCAT() / SUBSTRING_INDEX() hack:

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;

答案 1 :(得分:0)

如果您使用的是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; 

答案 2 :(得分:0)

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

SELECT m_id, year, MAX(number_loaned) FROM (SELECT m.from_museum_id AS m_id, m.year AS year, COUNT(*) AS number_loaned FROM museum_loan m GROUP BY m.from_museum_id, m.year HAVING COUNT(*) > 1) GROUP BY m_id;

答案 3 :(得分:0)

您可以模拟密集等级函数

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)