Нахождение максимального количества повторений значений в другом столбце

0

Поиск справки по MySQL Query.

У меня есть таблица, которая выглядит так (но это продолжается для многих других строк со многими разными значениями 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

Я пробовал реализовать sub-запрос в моей инструкции HAVING, которая пытается сравнить COUNT (*) с ним MAX безрезультатно. Я продолжаю получать только одну строку, в которой количество кредитов, предоставленных в кредит, является максимальным итогом, в результате чего:

from_museum_id  year    number_loaned
2               2015    4

Эта таблица довольно большая, и многие из m_museum_id считают, что любые трюки с ORDER BY и LIMIT не будут делать это для меня.

Я искал в течение часа, но, возможно, мои новички SQL-навыки мешают мне понять, как это решить (если бы это было только в Python/R, это было бы так просто!), Хотя может быть ответ где-то применимые к этому случаю.

Я ценю совет.

  • 0
    Это должно быть решено с использованием подзапроса / производной таблицы. См. Dev.mysql.com/doc/refman/8.0/en/derived-tables.html.
  • 0
    Я попробовал что-то вроде этого, но еще раз, он показывает мне только одну строку, где музей и год имели наибольшее количество кредитов, а не наибольшее количество, предоставленное для каждого музея и года. Я попытался добавить это в мое предложение HAVING: AND COUNT(*) = (SELECT MAX(cnt) FROM (SELECT COUNT(*) AS cnt FROM museum_loan m GROUP BY m.from_museum_id, m.year) sub);
Показать ещё 1 комментарий
Теги:

4 ответа

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() взломать:

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;
  • 0
    вы забыли COUNT (*)> 1 в своем выражении HAVING, но это было простое добавление, и, кроме того, эти запросы были элегантными и лаконичными. +1
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;

  • 0
    вы создаете псевдоним для производной таблицы, если вы сделаете отступ или отформатируете свой запрос SQL, вы бы его увидели. SQL должен быть читабельным, понятным и обслуживаемым, а SQL-строка не является таковой. Также ваш запрос не является ANSI SQL и неправильно использует функцию GROUP BY в MysQL, что означает, что он потерпит неудачу на серверах MySQL с ONLY_FULL_GROUP_BY sql_mode ... см. Демонстрационную версию sqlfiddle.com/#!9/25f61c/24
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)
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; 

Ещё вопросы

Сообщество Overcoder
Наверх
Меню