我正在尝试从MySQL表中提取数据并以一种日志文件格式插入到另一个表中。
说我有这张桌子。
TableA
+--------+----+-------+-------+-------+---------+
|UniqueID|Item|ColumnA|ColumnB|ColumnC|TimeStamp|
+--------+----+-------+-------+-------+---------+
|1 | 1 | 500 | 600 | 700 | 13:01 |
|2 | 2 | 50 | 60 | 70 | 13:03 |
|3 | 3 | 17 | 18 | 19 | 13:12 |
|4 | 1 | 501 | 600 | 700 | 13:15 |
|5 | 1 | 501 | 600 | 699 | 13:18 |
|6 | 3 | 20 | 18 | 19 | 13:22 |
|7 | 1 | 501 | 600 | 702 | 13:25 |
|8 | 2 | 50 | 66 | 70 | 13:26 |
|9 | 3 | 20 | 25 | 19 | 13:32 |
+--------+----+-------+-------+-------+---------+
会有多个表,其中包含不同数量的列和项目。 我不介意对表名和列名进行硬编码。
Id希望以该表结尾
+----+------+-------+--------+-------------+---------+
|Item|Table |Column |NewValue|PreviousValue|TimeStamp|
+----+------+-------+--------+-------------+---------+
| 1 |TableA|ColumnA| 501 | 500 | 13:15 |
| 1 |TableA|ColumnC| 699 | 700 | 13:18 |
| 3 |TableA|ColumnA| 20 | 17 | 13:22 |
| 1 |TableA|ColumnC| 699 | 702 | 13:25 |
| 2 |TableA|ColumnB| 66 | 60 | 13:26 |
| 3 |TableA|ColumnB| 25 | 18 | 13:32 |
+----+------+-------+--------+-------------+---------+
答案 0 :(得分:1)
MySQL并没有使它变得如此简单。您可以通过计算先前的时间戳然后将其加入来获得先前的记录。在MySQL 8.0中,您可以为此使用lag()
。
然后,您需要取消旋转值。 MySQL确实没有做到这一点,但是您可以使用cross join
和case
表达式。其余的只是条件逻辑和过滤:
select item, 'TableA' as tableName, colname,
col as newvalue, col_prev as prevvalue, timestamp
from (select t.*, c.colname,
(case when c.colname = 'columnA' then columnA
when c.colname = 'columnB' then columnB
when c.colname = 'columnC' then columnC
end) as col,
(case when c.colname = 'columnA' then tprev.columnA
when c.colname = 'columnB' then tprev.columnB
when c.colname = 'columnC' then tprev.columnC
end) as col_prev
from (select t.*,
(select max(t2.timestamp)
from tablea t2
where t2.item = t.item and t2.timestamp < t.timestamp
) as timestamp_prev
from tablea t
) t join
t tprev
on t.item = tprev.item and t.timestamp_prev = tprev.timestamp cross join
(select 'columnA' as colname union all
select 'columnB' as colname union all
select 'columnC' as colname
) c
) ct
where col_prev <> col;