MySQL: совокупные изменения для нескольких объектов из временной таблицы - PullRequest
0 голосов
/ 07 июня 2018

У меня есть такая таблица, где сохраняются все изменения статуса для каждого символа.

table characters_changes
+----+--------+---------+-------+----------------------+
| id |  rank  |   job   | money |      datetime        |
+----+--------+---------+-------+----------------------+
| 1  |   2    | tailor  |  25   | 2018-06-01 12:30:15  |
| 1  |   3    |  NULL   |   5   | 2018-06-02 10:50:19  |
| 1  |   2    |  NULL   |  -5   | 2018-06-03 18:44:35  |
| 1  |  NULL  | tinker  |  10   | 2018-06-04 04:10:12  |
| 1  |   3    |  NULL   | NULL  | 2018-06-05 17:31:00  |
|  2 |    1   |   spy   |   7   |  2018-06-01 12:30:15 |
|  2 |    2   |   NULL  |  NULL |  2018-06-02 10:50:19 |
|  2 |   NULL |  no job |   7   |  2018-06-03 17:31:00 |
| 3  |   3    | soldier |  12   | 2018-06-01 12:30:15  |
| 3  |   1    |  NULL   | -11   | 2018-06-02 10:50:19  |
+----+--------+---------+-------+----------------------+

NULL означает, что не было изменений в соответствующем атрибуте.изменение ранга и должности означает замену одного на другое, в то время как замена денег означает добавление и вычитание суммы (если не NULL).Гарантируется, как минимум, одна строка на символ без NULL -s.

Поэтому мне нужно получить таблицу, в которой я мог бы показать текущее состояние каждого символа в конце.С их последним званием, последней работой и полученной суммой денег.Таблица, подобная этой.

table characters_status
+----+--------+---------+-------+
| id |  rank  |   job   | money |
+----+--------+---------+-------+
| 1  |   3    | tinker  |  35   |
|  2 |    2   |  no job |   14  |
| 3  |   1    | soldier |   1   |
+----+--------+---------+-------+

Что еще хуже, таблица characters_changes является временной таблицей.datetime в нем происходит из другой таблицы событий.Так как это временно, я могу запросить его только один раз.Но может быть любое количество символов и, скорее всего, будет больше столбцов, таких как звание и должность.

Вся система необходима для обеспечения возможности получать статусы для всех персонажей в любой заданный момент времени, игнорируя все изменения после этого.Но эта часть легка для меня, поэтому я оставил ее вне рамок моего вопроса.

1 Ответ

0 голосов
/ 07 июня 2018

Это должно работать, я думаю:

SELECT id
   , CASE WHEN INSTR(ranks, '|') = 0 THEN ranks ELSE LEFT(ranks, INSTR(ranks, '|')-1) END AS rank
   , CASE WHEN INSTR(jobs, '|') = 0 THEN jobs ELSE LEFT(jobs, INSTR(jobs, '|')-1) END AS job
   , monies
FROM
(
   SELECT id
      , GROUP_CONCAT(rank ORDER BY datetime DESC SEPARATOR '|') AS ranks
      , GROUP_CONCAT(job ORDER BY datetime DESC SEPARATOR '|') AS jobs
      , SUM(money) AS monies
   FROM characters_changes
   GROUP BY id
) AS lists
;

Технически, вы можете сделать это без подзапроса, но я разбил его таким образом для ясности.Альтернативой могут быть такие выражения:

, CASE COUNT(rank) WHEN 0 THEN NULL WHEN 1 THEN GROUP_CONCAT(rank ORDER BY datetime DESC SEPARATOR '|') ELSE LEFT(GROUP_CONCAT(rank ORDER BY datetime DESC SEPARATOR '|'), INSTR(GROUP_CONCAT(rank ORDER BY datetime DESC SEPARATOR '|'), '|')-1) END AS rank

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...