使用SQL在数据库表中创建注释字段的历史记录

时间:2015-03-06 18:38:50

标签: sql oracle

我在Oracle数据库中有一个表,其中包含注释字段。我将其称为CLIENT_INFO表。

我正在尝试创建一个名为CLIENT_COMMENTS的新表。它会有适用于特定客户的时间戳注释。我没有只有一个评论字段,而是有一个关于客户的评论列表。

我还有一个跟踪CLIENT_INFO表的所有更改的历史记录表,我将称之为HIS_CLIENT_INFO。

使用历史记录表,我可以创建一个客户评论的视图,因为它们会随着时间的推移而变化:

SELECT CLIENT_ID, HIS_TIME, COMMENT FROM HIS_CLIENT_INFO ORDER BY CLIENT_ID;

结果将是这样的:

client_id | his_time             | comment
-------------------------------------------------------------------------
        1 | Mar-5-2014, 10:14 AM | Client is thirsty.
        1 | Mar-5-2014, 10:17 AM | Client is thirsty. Also he is hungry.
        2 | Mar-5-2014, 10:13 AM | This client is nice.
        2 | Mar-5-2014, 10:14 AM | This client is nice. He has a cool car.

请注意每次更新或更改客户的评论时,历史记录结果会显示新文本附加到旧文本。

我正在尝试创建一个这样的表:

client_id | his_time             | comment
-------------------------------------------------------------------------
        1 | Mar-5-2014, 10:14 AM | Client is thirsty.
        1 | Mar-5-2014, 10:17 AM | Also he is hungry.
        2 | Mar-5-2014, 10:13 AM | This client is nice.
        2 | Mar-5-2014, 10:14 AM | He has a cool car.

这里我只对评论进行了更新。这个新表有效地代表了当时输入的评论。

我并不担心删除了部分评论,他们应该只附加新文字。

有没有办法在SQL中生成这种表?

2 个答案:

答案 0 :(得分:3)

您可以使用lag()分析函数来回顾客户端的上一条评论,并将其与当前行进行比较,以确定这是否是前一条评论的附加版本。 (目前尚不清楚是否可以完全替换推荐或总是附加推荐)。如果是,请使用substr()删除当前评论。

select client_id, his_time,
  trim(case when lag_comment_text is null then
      comment_text
    when comment_text like lag_comment_text || '%' then
      substr(comment_text, length(lag_comment_text) + 1)
    else
      comment_text
    end) as new_comment_text
from (
  select client_id, his_time, comment_text, lag(comment_text)
      over (partition by client_id order by his_time) as lag_comment_text
  from his_client_info
);

 CLIENT_ID HIS_TIME              NEW_COMMENT_TEXT                        
---------- --------------------- ----------------------------------------
         1 Mar-05-2014, 10:14 AM Client is thirsty.                       
         1 Mar-05-2014, 10:17 AM Also he is hungry.                       
         2 Mar-05-2014, 10:13 AM This client is nice.                     
         2 Mar-05-2014, 10:14 AM He has a cool car.                       

SQL Fiddle demo

您可以将其用作create table ... as select(CTAS),或视图等。

答案 1 :(得分:0)

递归解决方案:

with tmp as (
  select row_number() over (partition by client_id order by his_time) rn,
      client_id cid, his_time ht, tcomment comm
    from his_client_info),
r(rn, cid, ht, comm, prior_rn, prior_cid) as (
  select rn, cid, ht, comm, null prior_rn, null prior_cid from tmp where rn=1
  union all
  select tmp.rn, tmp.cid, tmp.ht, trim(replace(tmp.comm, r.comm)), tmp.rn, tmp.ht 
    from tmp join r on tmp.cid = r.cid and tmp.rn = r.rn + 1)
select cid client_id, to_char(ht, 'mm-dd hh24:mi') his_time, 
    comm "comment" 
  from r order by cid, ht

结果:

client_id  his_time     comment
---------  -----------  -------------------
        1  03-05 10:14  Client is thirsty.
        1  03-05 10:17  Also he is hungry.
        2  03-05 10:13  This client is nice.
        2  03-05 10:14  He has a cool car.

当你为客户1添加评论&#34时的第三行时,他也很饿。他也生病了。" 你只得到最后一部分。