MySQL:聚合临时表中多个对象的更改

标签 mysql aggregate temporary

我有一个像这样的表,其中保存每个角色的每个状态更改。

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 。

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

更糟糕的是,表 characters_changes 是一个临时表。 其中的日期时间来自另一个事件表。 因为它是临时的,所以我只能查询一次。但可以有任意数量的字符,并且很可能会有更多的列,例如等级和工作。

整个系统需要提供在任何给定日期时间获取所有角色状态的可能性,而忽略此后的所有更改。但这部分对我来说很容易,所以我把它排除在我的问题范围之外。

最佳答案

我认为这应该有效:

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) (排名 ORDER BY 日期时间 DESC SEPARATOR '|'), '|')-1) END AS 排名

关于MySQL:聚合临时表中多个对象的更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50747509/

相关文章:

c++ - 使用带有虚函数的类的构造函数进行大括号初始化

r - 计算两个分组变量的每个组合的列总和

sql - 创建具有固定值的临时表

java - 临时变量的效率(例如java)

mysql - 在 Perl 中递增多维哈希

mysql - 困难的 Rails ActiveModel 查询

R 聚合和非空计数

Java 重用(静态?)对象作为临时对象以提高性能

php - 在 php mysql 中更新和插入查询时出错

mysql - rake db:迁移 rake 中止! Mysql2::错误:用户 'simple_cms' @'localhost' 的访问被拒绝(使用密码:是)