我有一张桌子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
...
一行中所有行动持续时间的OR摘要。
单个数据库查询是否可行? (不创建额外的表格)
答案 0 :(得分:2)
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
SQLFiddle Example for MSSQL but it has to work under Firebird too
答案 1 :(得分: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
答案 2 :(得分: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