Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在PL/SQL中通过时间戳隔离Oracle相关记录_Oracle_Plsql - Fatal编程技术网

在PL/SQL中通过时间戳隔离Oracle相关记录

在PL/SQL中通过时间戳隔离Oracle相关记录,oracle,plsql,Oracle,Plsql,我很抱歉,如果这是从任何重复。我在为这个问题的恰当措辞而挣扎 目前的问题涉及数据表日志。日志的架构为: USERID - Char(20) CODE - Number TIME - TimeStamp(6) COMMENT - CHAR(120) 此日志用于跟踪应用程序中的用户行为。在大多数情况下,所需要的只是时间戳,但某些活动正在被仔细审查,并要求报告。在这种情况下,受影响的项目是用于编辑帐户的打开和关闭值。0表示打开,1表示关闭。在本例中,注释保留帐户签名。例: MYUSER | 0

我很抱歉,如果这是从任何重复。我在为这个问题的恰当措辞而挣扎

目前的问题涉及数据表日志。日志的架构为:

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)
指示开始和结束时间的标记可能会被一个标识性整数替换,但这并不重要。真正的问题是在打开和关闭之间进行分组,以建立打开-关闭事件

根据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关闭事件(第二次保持打开状态)根本没有解决。我觉得这更接近我想要的,但仍然没有

设置

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;
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                                                                                          
查询1

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;
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                                                                                          
结果

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;
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                                                                                          

设置

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;
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                                                                                          
查询1

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;
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                                                                                          
结果

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;
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                                                                                          

你能提供具体的例子说明你期望的输入/输出是什么样的吗?让我来扮演一下经理。您想重写此应用程序。为了什么?这对你有什么好处?这怎么能不违反格言“如果它没有坏,就不要修理它”?谢谢。这是一个日志记录请求,在核心业务应用程序中不存在日志记录,不能在WinXP或Server 2003之后运行。Net应用程序是从20世纪90年代末的Access VBA脚本变异而来的,现代化的资源不可用(管理层抵制这种变化)。有太多的人参与了这段代码,微小的更改会导致到处都是bug。目标是提供以前不可用的业务指标,供管理层成员使用,以提高其部门内的绩效。需求,包括模式,都已经设置好了。你能提供具体的例子说明你期望输入/输出是什么样子吗?让我来扮演一下管理者。您想重写此应用程序。为了什么?这对你有什么好处?这怎么能不违反格言“如果它没有坏,就不要修理它”?谢谢。这是一个日志记录请求,在核心业务应用程序中不存在日志记录,不能在WinXP或Server 2003之后运行。Net应用程序是从20世纪90年代末的Access VBA脚本变异而来的,现代化的资源不可用(管理层抵制这种变化)。有太多的人参与了这段代码,微小的更改会导致到处都是bug。目标是提供以前不可用的业务指标,供管理层成员使用,以提高其部门内的绩效。需求,包括模式,都已经设置好了。非常接近,但不是很接近。我将把这个查询的结果作为编辑发布在相关数据的旁边。我知道我错过了一个简单的更改!非常感谢。非常接近,但不太接近。我将把这个查询的结果作为编辑发布在相关数据的旁边。我知道我错过了一个简单的更改!非常感谢。