【发布时间】:2018-06-14 19:27:33
【问题描述】:
有一个这样的表(“param”列不是4,而是例如10):
+-------------+-------------+---------------------+--------+--------+--------+--------+
| primary_key | logical_key | change_time | param1 | param2 | param3 | param4 |
+-------------+-------------+---------------------+--------+--------+--------+--------+
| 1 | 1 | 14.06.2018 22:00:00 | x | 1 | f | 3 |
| 2 | 1 | 14.06.2018 22:00:01 | y | 4 | e | 32 |
| 3 | 1 | 14.06.2018 22:00:02 | t | 12 | r | 32 |
| 4 | 1 | 14.06.2018 22:00:02 | t | 45 | d | 40 |
+-------------+-------------+---------------------+--------+--------+--------+--------+
它存储更改的完整历史记录。 也就是说,当有一个单元格的逻辑更新时 - 将一行插入到表中 复制此logical_key上前一行的所有值, 在这个新行中,只有正在更新的单元格的值是新的。
需要以这种形式显示更改参数的历史:
+------------+-----------+-----------+---------------------+
| param_name | old_value | new_value | change_time |
+------------+-----------+-----------+---------------------+
| param1 | null | x | 14.06.2018 22:00:00 |
| param2 | null | 1 | 14.06.2018 22:00:00 |
| param3 | null | f | 14.06.2018 22:00:00 |
| param4 | null | 3 | 14.06.2018 22:00:00 |
| param1 | x | y | 14.06.2018 22:00:01 |
| param2 | 1 | 4 | 14.06.2018 22:00:01 |
| param3 | f | e | 14.06.2018 22:00:01 |
| param4 | 3 | 32 | 14.06.2018 22:00:01 |
| param1 | y | t | 14.06.2018 22:00:02 |
| param2 | 4 | 12 | 14.06.2018 22:00:02 |
| param3 | e | r | 14.06.2018 22:00:02 |
| param2 | 12 | 45 | 14.06.2018 22:00:02 |
| param3 | r | d | 14.06.2018 22:00:02 |
| param4 | 32 | 40 | 14.06.2018 22:00:02 |
+------------+-----------+-----------+---------------------+
我是这样实现的:
select * from
(select
'param1' as param_name,
nvl(to_char(lag(t.param1) over (order by t.primary_key)), 'null') as old_value,
nvl(to_char(t.param1), 'null') as new_value,
t.change_time
from my_table t
where t.logical_key = :pLogical_key) tt
where tt.old_value <> tt.new_value
union all
select * from
(select
'param2' as param_name,
nvl(to_char(lag(t.param2) over (order by t.primary_key)), 'null') as old_value,
nvl(to_char(t.param2), 'null') as new_value,
t.change_time
from my_table t
where t.logical_key = :pLogical_key) tt
where tt.old_value <> tt.new_value
/* union all etc. */
order by 4, 1
但这显然不是可以使用的东西。 我怎样才能让它被接受?
【问题讨论】:
-
Oracle 有一个
UNPIVOT子句,可以将列降为行。
标签: sql oracle pivot window-functions