2013-07-09 42 views
2

加入我有一个表STARTSTOP火鸟 - 自上一个表

ACTION DATA     ID_PPSTARTSTOPPOZ 
0 2013-03-18 08:38:00 10451 
1 2013-03-18 09:00:00 10453 
0 2013-03-18 09:50:00 10466 
1 2013-03-18 10:38:00 10467 
0 2013-03-19 11:54:00 10499 
1 2013-03-19 12:32:00 10505 

动作0 - >启动操作 行动1 - >停止动作 DATA是行动的时间戳

我想运行select返回记录的语句如下所示:

ACTION_1 ACTION_2 DURATION 
10451  10453  22 
10466  10466  48 
      ... 

或所有操作的摘要持续时间在一行中。

单个数据库查询可行吗? (而无需创建附加表)

回答

1
select A1.ID_PPSTARTSTOPPOZ as Action_0, 
     A2.Action_1, 
     datediff (minute, A1.DATA ,A2.DATA) 

from STARTSTOP A1 
JOIN 
(
    select ID_PPSTARTSTOPPOZ as Action_1, 
     DATA, 
     (select max(ID_PPSTARTSTOPPOZ) 
      FROM STARTSTOP 
      where ID_PPSTARTSTOPPOZ<T.ID_PPSTARTSTOPPOZ 
       AND 
       ACTION=0) AS PREV_ACTION 
    from STARTSTOP T 
    where ACTION=1 

) A2 on A1.ID_PPSTARTSTOPPOZ=A2.PREV_ACTION 

where ACTION = 0 
order by A1.ID_PPSTARTSTOPPOZ 

DATEDIFF function

SQLFiddle Example for MSSQL but it has to work under Firebird too

+0

进行比较。谢谢。它像魅力一样工作。 – zeno33

0

它可以用一个单一的选择来实现,但算法EXECUTE BLOCK会做更快:

EXECUTE BLOCK 
    RETURNS (ACTION_1 INTEGER, ACTION_2 INTEGER, DURATION INTEGER) 
AS 
    DECLARE VARIABLE act INTEGER; 
    DECLARE VARIABLE act_id INTEGER; 
    DECLARE VARIABLE d TIMESTAMP = NULL; 
    DECLARE VARIABLE d1 TIMESTAMP = NULL; 
BEGIN 
    FOR 
    SELECT action, data, id_ppstartstoppoz 
    FROM startstop 
    ORDER BY data ASC 
    INTO :act, :d, :act_id 
    DO BEGIN 
    IF (:act = 0) THEN 
    BEGIN 
     d1 = :d; 
     action_1 = :act_id; 
    END ELSE 
    BEGIN 
     IF (NOT :d1 IS NULL) THEN 
     BEGIN 
     action_2 = :act_id; 
     duration = DATEDIFF(SECOND, :d1, :d); 
     SUSPEND; 
     d1 = NULL; 
     END 
    END 
    END 
END 
+0

谢谢。我会尝试将其与@valex解决方案 – zeno33

0

这可以以更简单的方式完成

SELECT TAB1.ID AS ACTION_1,TAB2.ID AS ACTION_2, 
(TAB2.DATA_TS - TAB1.DATA_TS) MINUTE (4) TO SECOND(6) AS DURATION 
FROM 

(SELECT ID, DATA_TS , ROW_NUMBER() OVER (ORDER BY ID)AS RNUM FROM 
PROCESS WHERE ACTION=0 
)TAB1 

INNER JOIN 

(SELECT ID, DATA_TS , ROW_NUMBER() OVER (ORDER BY ID) AS RNUM FROM  
    PROCESS WHERE ACTION=1 
) TAB2 

ON (TAB1.RNUM=TAB2.RNUM) 
ORDER BY 1 

    ACTION_1 ACTION_2 DURATION 
    10,451 10,453  22:00.000000 
    10,466 10,467  48:00.000000 
    10,499 10,505  38:00.000000