通过PL / SQL

时间:2015-12-16 14:01:05

标签: oracle plsql

如果这与任何内容重复,我道歉。我正在努力解决问题的正确措辞。

手头的问题涉及数据表 LOG 。 Log的架构是:

USERID - Char(20) 
CODE - Number 
TIME - TimeStamp(6) 
COMMENT - CHAR(120)

此日志用于跟踪应用程序中的用户行为。在大多数情况下,所需要的只是时间戳,但正在审查某些活动并要求报告。在这种情况下,受影响的项目是用于编辑帐户的打开和关闭值。 0表示打开,1表示关闭。在这种情况下,评论持有帐户签名。例如:

MYUSER | 0 | 12-DEC-2014 x.yy.zz | 776655-4
MYUSER | 7 | 12-DEC-2014 x.aa.bb | Did Stuff  
MYUSER | 1 | 12-DEC-2014 x.aa.cc | 776655-4

预期的情况是,用户可能同时打开多个帐户,并且在桌面上运行查询之前,用户可能已经或可能没有关闭开放帐户。此外,用户可以关闭帐户,然后再打开帐户,创建具有相同帐号的多个开 - 关对实例。唯一不可能发生的事情是帐户不能同时打开两次,甚至不能由同一个用户打开(它被“锁定以进行编辑”和“签出”)。当然,这也意味着一个用户无法关闭其他用户帐户。

我要做的是提供所需的时间跨度。虽然这将与旧的.Net程序接口,但它的.Net版本是1.1(我知道),我宁愿不鼓励我们可以继续编辑已有10年历史的软件而不是替换它,如果我可以避免它。这意味着在包中使用存储过程的PL / SQL解决方案。我可以很容易地比较两个记录的时间,但是我很难将PL / SQL放在一起以确保我得到每个逻辑开关事件对的时间跨度。有什么建议吗?

编辑以回应评论:

预期输出将是每个“事件”和持续时间,例如下面的。

USERID | <open_timestamp> => <close_timestamp> | duration (as hh.mm.ss.xxxxxx)

MYUSER | 14-NOV-2032 hh.mm.ss.dddd => 14-NOV-2032 hh.mm.ss.xxxx | rr.ee.ss.ult

指示开始和结束时间的标记可能会被标识整数替换,但这并不重要。真正的问题是在开放和结束之间进行分组以建立开闭事件

编辑以响应MT0的第一个回答:

这几乎就在那里,但遗憾的是,当帐户被多次打开但未必关闭时,错误处理了结束事件。这是表中的示例数据。

------OPENS-------
User   | Account| Account Open Time
MYUSER | 738056 | 16-DEC-15 08.14.27.239780000 AM 
MYUSER | 738152 | 16-DEC-15 08.06.07.702045000 AM 
MYUSER | 738056 | 16-DEC-15 07.47.28.825647000 AM 
MYUSER | 738152 | 16-DEC-15 07.44.11.168721000 AM 

------CLOSES---------
User   | Account| Account Closed Time             
MYUSER | 738056 | 16-DEC-15 08.14.49.313336000 AM 
MYUSER | 738152 | 16-DEC-15 08.06.05.657541000 AM 
MYUSER | 738056 | 16-DEC-15 08.05.49.333156000 AM 

-----RESULT OF MT0's ANSWER------------
USER | ACCOUNT | OPEN_TIME                         | CLOSE_TIME                       | DURATION
MYUSER | 738152| 16-DEC-2015 07.44.11.168721168721 | 16-DEC-2015 08.05.49.333156333156| +000000000 00:21:38.164435  
MYUSER | 738056| 16-DEC-2015 07.47.28.825647825647 | 16-DEC-2015 08.05.49.333156333156| +000000000 00:18:20.507509  
MYUSER | 738152| 16-DEC-2015 08.06.07.702045702045 | 16-DEC-2015 08.14.49.313336313336| +000000000 00:08:41.611291  
MYUSER | 738056| 16-DEC-2015 08.14.27.239780239780 | 16-DEC-2015 08.14.49.313336313336| +000000000 00:00:22.073556  

请注意与738056关联的时间如何用于关闭两个帐户,但738152关闭事件(第二次保持打开状态)根本没有解决。我觉得这更接近我正在寻找的东西,但还没有。

1 个答案:

答案 0 :(得分:0)

<强>设置

CREATE TABLE LOG ( UserID, Code, Account, Time ) AS
          SELECT 'MYUSER', 0, 738056, TIMESTAMP '2015-12-16 08:14:27.239780000' FROM DUAL
UNION ALL SELECT 'MYUSER', 0, 738152, TIMESTAMP '2015-12-16 08:06:07.702045000' FROM DUAL
UNION ALL SELECT 'MYUSER', 0, 738056, TIMESTAMP '2015-12-16 07:47:28.825647000' FROM DUAL
UNION ALL SELECT 'MYUSER', 0, 738152, TIMESTAMP '2015-12-16 07:44:11.168721000' FROM DUAL
UNION ALL SELECT 'MYUSER', 1, 738056, TIMESTAMP '2015-12-16 08:14:49.313336000' FROM DUAL
UNION ALL SELECT 'MYUSER', 1, 738152, TIMESTAMP '2015-12-16 08:06:05.657541000' FROM DUAL 
UNION ALL SELECT 'MYUSER', 1, 738056, TIMESTAMP '2015-12-16 08:05:49.333156000' FROM DUAL;

查询1

SELECT UserID,
       Account,
       TO_CHAR( Open_Time, 'DD-MON-YYYY HH24.MI.SS.FFFF' ) AS Open_Time,
       TO_CHAR( Close_Time, 'DD-MON-YYYY HH24.MI.SS.FFFF' ) AS Close_Time,
       TO_CHAR( Close_Time - Open_Time, 'HH24.MI.SS.FFFFFF' ) AS Duration
FROM   (
  SELECT UserID,
         Account,
         Code,
         Time AS Open_Time,
         LEAD( CASE CODE WHEN 1 THEN TIME END ) IGNORE NULLS OVER ( PARTITION BY UserID, Account ORDER BY Time ) AS Close_Time
  FROM   Log
  WHERE  CODE IN ( 0, 1 )
)
WHERE CODE = 0;

<强>结果:

USERID    ACCOUNT OPEN_TIME                                        CLOSE_TIME                                       DURATION                     
------ ---------- ------------------------------------------------ ------------------------------------------------ ------------------------------
MYUSER     738056 16-DEC-2015 07.47.28.825647000825647000          16-DEC-2015 08.05.49.333156000333156000          +000000000 00:18:20.507509000  
MYUSER     738056 16-DEC-2015 08.14.27.239780000239780000          16-DEC-2015 08.14.49.313336000313336000          +000000000 00:00:22.073556000  
MYUSER     738152 16-DEC-2015 07.44.11.168721000168721000          16-DEC-2015 08.06.05.657541000657541000          +000000000 00:21:54.488820000  
MYUSER     738152 16-DEC-2015 08.06.07.702045000702045000