Предположим, у нас есть эта таблица mytable
:
+--------+-------+-----+
| City | User | Amt |
+--------+-------+-----+
| London | John | 100 |
| London | John | 200 |
| London | James | 300 |
| London | James | 50 |
| Paris | Jean | 100 |
+--------+-------+-----+
Я хочу написать запрос, который привел бы к следующему результату:
+--------+-------+------------+------------+
| City | User | AmtPerUser | AmtPerCity |
+--------+-------+------------+------------+
| London | John | 300 | 650 |
| London | James | 350 | 650 |
| Paris | Jean | 100 | 100 |
+--------+-------+------------+------------+
Это можно сделать с помощью следующего запроса:
SELECT t1.City, User, AmtPerUser, AmtPerCity
FROM
(SELECT City, User, SUM(Amt) as AmtPerUser FROM mytable GROUP BY City, User) t1
JOIN
(SELECT City, SUM(Amt) as AmtPerCity FROM mytable GROUP BY City ) t2
USING (City);
Но этот запрос выполняется слишком медленно, потому что у производных таблиц нет индексов.
Так что мне интересно, есть ли более эффективный способ выполнить эту задачу.
03/25/2019 ОБНОВЛЕНИЕ
Спасибо за предоставленные решения. В настоящее время я все еще использую старый MySQL 5.1.
Полезно знать о оконных функциях в MySQL 8.
Я проверил запросы на большем наборе (данные, перечисленные здесь, скопированы 3600 раз, чтобы получить 18К строк). Это лучший на сегодняшний день:
SELECT City, User, SUM(Amt) as AmtPerUser,
SUM(SUM(Amt)) OVER (PARTITION BY City) as AmtPerCity
FROM mytable
GROUP BY City, User;
Демонстрация на DB Fiddle
@ GordonLinoff: 43мс
Мой оригинальный запрос: 70мс
@GMB: 135 мс
Также оказалось, что наличие или отсутствие индексов не способствует.