Поиск справки по 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, это было бы так просто!), Хотя может быть ответ где-то применимые к этому случаю.
Я ценю совет.
Запрос, который вы ищете, это:
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;
Попробуйте запросить результат исходного запроса, используя его как производную таблицу:
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;
Вы можете моделировать плотную ранговую функцию
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)
Вы можете попробовать это, если используете 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;
AND COUNT(*) = (SELECT MAX(cnt) FROM (SELECT COUNT(*) AS cnt FROM museum_loan m GROUP BY m.from_museum_id, m.year) sub);