Создание ранга от наименьшей суммы до наибольшей группы сумм по нескольким столбцам
В настоящее время я использую MySQL 5.6.30, и мне нужна ваша помощь.
Вот данные в таблице, имя которой temp_work
+----+-----------+----------+----------+--------+---------+-------+---------+
| id | client_id | account | category | t_year | t_month | t_day | amount |
+----+-----------+----------+----------+--------+---------+-------+---------+
| 1 | 100 | Saving | deposit | 2016 | 12 | 14 | 100.84 |
| 2 | 100 | Checking | withdraw | 2016 | 12 | 15 | 300.24 |
| 3 | 100 | Checking | deposit | 2016 | 12 | 29 | 60.00 |
| 4 | 101 | Saving | Withdraw | 2016 | 12 | 29 | 245.16 |
| 5 | 100 | Saving | Withdraw | 2016 | 12 | 30 | 2200.00 |
| 6 | 100 | Checking | Withdraw | 2016 | 12 | 30 | 2372.16 |
| 7 | 100 | Saving | deposit | 2016 | 12 | 30 | 4327.00 |
| 8 | 101 | Checking | Withdraw | 2017 | 1 | 3 | 80.00 |
| 9 | 101 | Checking | Withdraw | 2017 | 1 | 3 | 1033.45 |
| 10 | 100 | Saving | Withdraw | 2017 | 1 | 3 | 1339.16 |
| 11 | 100 | Checking | deposit | 2017 | 1 | 4 | 140.00 |
| 12 | 100 | Checking | Withdraw | 2017 | 1 | 4 | 216.73 |
| 13 | 101 | Checking | Withdraw | 2017 | 1 | 4 | 1261.72 |
+----+-----------+----------+----------+--------+---------+-------+---------+
И мне нужен ранг от самой низкой суммы до самой большой группы сумм по client_id, счету, категории, t_year, t_month.
Итак, это то, что я ожидал или подобное
+-----------+----------+----------+--------+---------+---------+------+
| client_id | account | category | t_year | t_month | amount | rank |
+-----------+----------+----------+--------+---------+---------+------+
| 100 | Checking | deposit | 2016 | 12 | 60.00 | 1 |
| 100 | Checking | deposit | 2017 | 1 | 140.00 | 1 |
| 100 | Checking | withdraw | 2016 | 12 | 300.24 | 1 |
| 100 | Checking | withdraw | 2016 | 12 | 2327.16 | 2 |
| 100 | Checking | Withdraw | 2017 | 1 | 216.73 | 1 |
| 100 | Saving | deposit | 2016 | 12 | 100.84 | 1 |
| 100 | Saving | deposit | 2016 | 12 | 4327.00 | 2 |
| 100 | Saving | Withdraw | 2016 | 12 | 2200.00 | 1 |
| 100 | Saving | Withdraw | 2017 | 1 | 1339.16 | 1 |
| 101 | Checking | Withdraw | 2017 | 1 | 80.00 | 1 |
| 101 | Checking | Withdraw | 2017 | 1 | 1033.45 | 2 |
| 101 | Checking | Withdraw | 2017 | 1 | 1261.72 | 3 |
| 101 | Saving | Withdraw | 2016 | 12 | 245.16 | 1 |
+-----------+----------+----------+--------+---------+---------+------+
Вот моя первая попытка:
Select
tw1.client_id, tw1.account, tw1.category, tw1.t_year, tw1.t_month, tw1.amount
,@rownum = case when @tmonth <> tw1.t_month then 0 else @rownum + 1 end as ranking
,@tmonth := t_month as cmonth
From
( Select @rownum := 0 from dual ) as r,
( Select @tmonth := 0 from dual ) as m,
( Select client_id, account, category, t_year, t_month, amount
From temp_work as tw
Order by client_id, account, category, t_year, t_month, amount) as tw1
Вторая попытка:
Select tw1.client_id, tw1.account, tw1.category, tw1.t_year, tw1.t_month, tw1.amount
,@rownum = case when concat(@tyear, '-', @tmonth) <> concat(t_year, '-', t_month) then 0 else @rownum + 1 end as rank
,@tyear := t_year as cyear
,@tmonth := t_month as cmonth
From
( Select @rownum := 0 ) as r,
( Select @tyear := 0 ) as y,
( Select @tmonth := 0 ) as m,
(
Select client_id, account, category, t_year, t_month, amount
From temp_work
Order by tw.client_id, tw.account, tw.category, t_year, t_month, tw.amount
) as tw1
Однако, вышеуказанные запросы дают мне тот же результат, что и ниже.
+-----------+----------+----------+--------+---------+---------+------+
| client_id | account | category | t_year | t_month | amount | rank |
+-----------+----------+----------+--------+---------+---------+------+
| 100 | Checking | deposit | 2016 | 12 | 60.00 | 1 |
| 100 | Checking | deposit | 2017 | 1 | 140.00 | 1 |
| 100 | Checking | withdraw | 2016 | 12 | 300.24 | 1 |
| 100 | Checking | withdraw | 2016 | 12 | 2327.16 | 0 |
| 100 | Checking | Withdraw | 2017 | 1 | 216.73 | 1 |
| 100 | Saving | deposit | 2016 | 12 | 100.84 | 1 |
| 100 | Saving | deposit | 2016 | 12 | 4327.00 | 0 |
| 100 | Saving | Withdraw | 2016 | 12 | 2200.00 | 1 |
| 100 | Saving | Withdraw | 2017 | 1 | 1339.16 | 1 |
| 101 | Checking | Withdraw | 2017 | 1 | 80.00 | 1 |
| 101 | Checking | Withdraw | 2017 | 1 | 1033.45 | 0 |
| 101 | Checking | Withdraw | 2017 | 1 | 1261.72 | 0 |
| 101 | Saving | Withdraw | 2016 | 12 | 245.16 | 1 |
+-----------+----------+----------+--------+---------+---------+------+
Пожалуйста, дайте мне подсказка, чтобы решить эту проблему.
Большое вам спасибо.
2 ответа:
Рассмотрим коррелированный подсчет агрегированного подзапроса для ранжирования:
SELECT t.client_id, t.account, t.category, t.t_year, t.t_month, t.amount, (SELECT COUNT(*) FROM temp_work sub WHERE sub.amount <= t.amount AND sub.client_id = t.client_id AND sub.account = t.account AND sub.t_year = t.t_year AND sub.t_month = t.t_Month) AS rank FROM temp_work t ORDER BY t.client_id, t.account, t.category, t.t_year, t.t_month, t.amount
Попробуйте перестроить свой ордер по инструкции, чтобы ваша "сумма"была вторым значением в ордере по. Это приблизит вас к тому, чего вы хотите.
Порядок, в котором вы перечисляете столбцы, определяет порядок их сортировки.
Order by client_id, amount, account, category, t_year, t_month
Для получения дополнительной информации: https://dev.mysql.com/doc/refman/5.7/en/sorting-rows.html