2013-07-09 2 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 -> ACTION에게 START 조치 1 -> 데이터

내가 싶습니다 행동의 타임 스탬프입니다 STOP 액션 다음과 같이 레코드를 반환하는 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 
    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 
관련 문제