DB2 SQL Добавление значений столбцов - PullRequest
0 голосов
/ 02 апреля 2020

Я пытаюсь добавить некоторые вычисляемые столбцы вместе, где значения из этих столбцов являются подстрока функции разницы меток времени между текущей записью и следующей записью. К сожалению, подстрока возвращает нулевые значения, и я попытался преобразовать их через COALESCE, ISNULL, и я нигде не получаю с этим, чтобы эти значения добавить правильно. Я также пытался использовать функцию SUM, но я также получаю сообщение об ошибке.

select T01."ENGVIDN", T01."ENGSTAT", (TIMESTAMP(((SUBSTR( T01."ENGSTME", 1, LOCATE('T', T01."ENGSTME")-1))),(SUBSTR( T01."ENGSTME", LOCATE('T', T01."ENGSTME")+1, 8)))) as "T01 TIMESTAMP",  (TIMESTAMP(((SUBSTR( T02."ENGSTME", 1, LOCATE('T', T02."ENGSTME")-1))),(SUBSTR( T02."ENGSTME", LOCATE('T', T02."ENGSTME")+1, 8)))) as "T02 TIMESTAMP",  
CAST(((TIMESTAMP(((SUBSTR( T02."ENGSTME", 1, LOCATE('T', T02."ENGSTME")-1))),(SUBSTR( T02."ENGSTME", LOCATE('T', T02."ENGSTME")+1, 8)))) - (TIMESTAMP(((SUBSTR( T01."ENGSTME", 1, LOCATE('T', T01."ENGSTME")-1))),(SUBSTR( T01."ENGSTME", LOCATE('T', T01."ENGSTME")+1, 8))))) as INT) as "DIFF",
CAST(SUBSTR(((TIMESTAMP(((SUBSTR( T02."ENGSTME", 1, LOCATE('T', T02."ENGSTME")-1))),(SUBSTR( T02."ENGSTME", LOCATE('T', T02."ENGSTME")+1, 8)))) - (TIMESTAMP(((SUBSTR( T01."ENGSTME", 1, LOCATE('T', T01."ENGSTME")-1))),(SUBSTR( T01."ENGSTME", LOCATE('T', T01."ENGSTME")+1, 8))))), LOCATE('.', ((TIMESTAMP(((SUBSTR( T02."ENGSTME", 1, LOCATE('T', T02."ENGSTME")-1))),(SUBSTR( T02."ENGSTME", LOCATE('T', T02."ENGSTME")+1, 8)))) - (TIMESTAMP(((SUBSTR( T01."ENGSTME", 1, LOCATE('T', T01."ENGSTME")-1))),(SUBSTR( T01."ENGSTME", LOCATE('T', T01."ENGSTME")+1, 8))))))-8, 2)as INT) as "DAYS",
CAST(SUBSTR(((TIMESTAMP(((SUBSTR( T02."ENGSTME", 1, LOCATE('T', T02."ENGSTME")-1))),(SUBSTR( T02."ENGSTME", LOCATE('T', T02."ENGSTME")+1, 8)))) - (TIMESTAMP(((SUBSTR( T01."ENGSTME", 1, LOCATE('T', T01."ENGSTME")-1))),(SUBSTR( T01."ENGSTME", LOCATE('T', T01."ENGSTME")+1, 8))))), LOCATE('.', ((TIMESTAMP(((SUBSTR( T02."ENGSTME", 1, LOCATE('T', T02."ENGSTME")-1))),(SUBSTR( T02."ENGSTME", LOCATE('T', T02."ENGSTME")+1, 8)))) - (TIMESTAMP(((SUBSTR( T01."ENGSTME", 1, LOCATE('T', T01."ENGSTME")-1))),(SUBSTR( T01."ENGSTME", LOCATE('T', T01."ENGSTME")+1, 8))))))-6, 2) as INT) as "HOURS",
CAST(SUBSTR(((TIMESTAMP(((SUBSTR( T02."ENGSTME", 1, LOCATE('T', T02."ENGSTME")-1))),(SUBSTR( T02."ENGSTME", LOCATE('T', T02."ENGSTME")+1, 8)))) - (TIMESTAMP(((SUBSTR( T01."ENGSTME", 1, LOCATE('T', T01."ENGSTME")-1))),(SUBSTR( T01."ENGSTME", LOCATE('T', T01."ENGSTME")+1, 8))))), LOCATE('.', ((TIMESTAMP(((SUBSTR( T02."ENGSTME", 1, LOCATE('T', T02."ENGSTME")-1))),(SUBSTR( T02."ENGSTME", LOCATE('T', T02."ENGSTME")+1, 8)))) - (TIMESTAMP(((SUBSTR( T01."ENGSTME", 1, LOCATE('T', T01."ENGSTME")-1))),(SUBSTR( T01."ENGSTME", LOCATE('T', T01."ENGSTME")+1, 8))))))-4, 2) as INT) as "MINUTES",
CAST(SUBSTR(((TIMESTAMP(((SUBSTR( T02."ENGSTME", 1, LOCATE('T', T02."ENGSTME")-1))),(SUBSTR( T02."ENGSTME", LOCATE('T', T02."ENGSTME")+1, 8)))) - (TIMESTAMP(((SUBSTR( T01."ENGSTME", 1, LOCATE('T', T01."ENGSTME")-1))),(SUBSTR( T01."ENGSTME", LOCATE('T', T01."ENGSTME")+1, 8))))), LOCATE('.', ((TIMESTAMP(((SUBSTR( T02."ENGSTME", 1, LOCATE('T', T02."ENGSTME")-1))),(SUBSTR( T02."ENGSTME", LOCATE('T', T02."ENGSTME")+1, 8)))) - (TIMESTAMP(((SUBSTR( T01."ENGSTME", 1, LOCATE('T', T01."ENGSTME")-1))),(SUBSTR( T01."ENGSTME", LOCATE('T', T01."ENGSTME")+1, 8))))))-2, 2) as INT) as "SECONDS",
--
(CAST(SUBSTR(((TIMESTAMP(((SUBSTR( T02."ENGSTME", 1, LOCATE('T', T02."ENGSTME")-1))),(SUBSTR( T02."ENGSTME", LOCATE('T', T02."ENGSTME")+1, 8)))) - (TIMESTAMP(((SUBSTR( T01."ENGSTME", 1, LOCATE('T', T01."ENGSTME")-1))),(SUBSTR( T01."ENGSTME", LOCATE('T', T01."ENGSTME")+1, 8))))), LOCATE('.', ((TIMESTAMP(((SUBSTR( T02."ENGSTME", 1, LOCATE('T', T02."ENGSTME")-1))),(SUBSTR( T02."ENGSTME", LOCATE('T', T02."ENGSTME")+1, 8)))) - (TIMESTAMP(((SUBSTR( T01."ENGSTME", 1, LOCATE('T', T01."ENGSTME")-1))),(SUBSTR( T01."ENGSTME", LOCATE('T', T01."ENGSTME")+1, 8))))))-4, 2) as INT)*60 +
CAST(SUBSTR(((TIMESTAMP(((SUBSTR( T02."ENGSTME", 1, LOCATE('T', T02."ENGSTME")-1))),(SUBSTR( T02."ENGSTME", LOCATE('T', T02."ENGSTME")+1, 8)))) - (TIMESTAMP(((SUBSTR( T01."ENGSTME", 1, LOCATE('T', T01."ENGSTME")-1))),(SUBSTR( T01."ENGSTME", LOCATE('T', T01."ENGSTME")+1, 8))))), LOCATE('.', ((TIMESTAMP(((SUBSTR( T02."ENGSTME", 1, LOCATE('T', T02."ENGSTME")-1))),(SUBSTR( T02."ENGSTME", LOCATE('T', T02."ENGSTME")+1, 8)))) - (TIMESTAMP(((SUBSTR( T01."ENGSTME", 1, LOCATE('T', T01."ENGSTME")-1))),(SUBSTR( T01."ENGSTME", LOCATE('T', T01."ENGSTME")+1, 8))))))-2, 2) as INT))



from mrc_main."SAMENGST" T01 
        INNER JOIN mrc_main."SAMENGST" T02 on RRN(T02) = RRN(T01)+1
                and (TIMESTAMP(((SUBSTR( T02."ENGSTME", 1, LOCATE('T', T02."ENGSTME")-1))),(SUBSTR( T02."ENGSTME", LOCATE('T', T02."ENGSTME")+1, 8)))) > (TIMESTAMP(((SUBSTR( T01."ENGSTME", 1, LOCATE('T', T01."ENGSTME")-1))),(SUBSTR( T01."ENGSTME", LOCATE('T', T01."ENGSTME")+1, 8))))


WHERE T01."ENGVIDN" = T02."ENGVIDN" and
        T02."ENGVIDN" = 212014918948687 and 
        T01."ENGSTME" like '%2020-02-17%' 

Я пытаюсь добавить столбцы, помеченные как ДНИ, ЧАСЫ, МИНУТЫ, СЕКУНДЫ, так что бы правильный путь к свершившийся sh это?

Пример данных ниже

ENGVIDN         ENGSTME                 ENGSTME
212014918948687 2020-02-17T09:46:19Z    Off
212014918948687 2020-02-17T09:46:29Z    On
212014918948687 2020-02-17T09:50:10Z    Idle
212014918948687 2020-02-17T10:01:11Z    On
212014918948687 2020-02-17T10:12:16Z    Idle
212014918948687 2020-02-17T11:10:17Z    On
212014918948687 2020-02-17T11:19:27Z    Idle
212014918948687 2020-02-17T11:23:27Z    On
212014918948687 2020-02-17T11:35:19Z    Idle
212014918948687 2020-02-17T11:36:53Z    Off
212014918948687 2020-02-17T12:07:20Z    On
212014918948687 2020-02-17T12:09:20Z    Idle
212014918948687 2020-02-17T12:21:01Z    On
212014918948687 2020-02-17T12:38:48Z    Idle
212014918948687 2020-02-17T12:39:47Z    On
212014918948687 2020-02-17T12:53:44Z    Idle
212014918948687 2020-02-17T12:56:23Z    On
212014918948687 2020-02-17T12:58:48Z    Idle
212014918948687 2020-02-17T13:01:14Z    On
212014918948687 2020-02-17T13:17:17Z    Idle
212014918948687 2020-02-17T14:01:01Z    On
212014918948687 2020-02-17T14:09:16Z    Idle
212014918948687 2020-02-17T14:41:29Z    On
212014918948687 2020-02-17T15:01:19Z    Off
212014918948687 2020-02-17T15:35:42Z    On
212014918948687 2020-02-17T15:43:11Z    Off
212014918948687 2020-02-17T16:16:57Z    On
212014918948687 2020-02-17T16:26:36Z    Idle
212014918948687 2020-02-17T16:50:30Z    On
212014918948687 2020-02-17T16:58:20Z    Idle
212014918948687 2020-02-17T17:03:24Z    On
212014918948687 2020-02-17T17:13:30Z    Idle
212014918948687 2020-02-17T17:23:16Z    On
212014918948687 2020-02-17T17:36:51Z    Off
212014918948687 2020-02-17T19:00:35Z    On
212014918948687 2020-02-17T19:19:31Z    Off
212014918948687 2020-02-17T19:21:58Z    On
212014918948687 2020-02-17T19:24:09Z    Idle
212014918948687 2020-02-17T19:26:08Z    On
212014918948687 2020-02-17T19:42:24Z    Idle
212014918948687 2020-02-17T19:44:27Z    On
212014918948687 2020-02-17T19:48:55Z    Off
212014918948687 2020-02-17T19:50:53Z    On
212014918948687 2020-02-17T19:57:27Z    Off
212014918948687 2020-02-18T01:55:56Z    On
212014918948687 2020-02-18T01:58:43Z    Off
212014918948687 2020-02-18T05:02:17Z    Off
212014918948687 2020-02-18T08:58:01Z    On
212014918948687 2020-02-18T09:01:45Z    Idle
212014918948687 2020-02-18T09:05:17Z    On

1 Ответ

2 голосов
/ 03 апреля 2020

Я не уверен, но кажется, что это V7.1.
Попробуйте это как:

WITH TAB (ENGSTME) AS 
(
VALUES
  TIMESTAMP('2020-02-17-09.46.19')
, TIMESTAMP('2020-02-17-09.46.29')
, TIMESTAMP('2020-02-17-09.50.10')
, TIMESTAMP('2020-02-17-10.01.11')
, TIMESTAMP('2020-02-17-10.12.16')
, TIMESTAMP('2020-02-17-11.10.17')
)
, TAB_ENUM (RN, ENGSTME) AS 
(
SELECT ROWNUMBER() OVER (ORDER BY ENGSTME) AS RN, ENGSTME
FROM TAB
)
SELECT 
  A.ENGSTME, B.ENGSTME AS ENGSTME_PREV
, DIGITS(DEC(A.ENGSTME - B.ENGSTME, 14)) AS TS_DURATION --yyyymmddhhmmss format with leading zeroes
, (DAYS(A.ENGSTME) - DAYS(B.ENGSTME)) * 86400 + MIDNIGHT_SECONDS(A.ENGSTME) - MIDNIGHT_SECONDS(B.ENGSTME) AS TS_DIFF_SEC
FROM TAB_ENUM A
LEFT JOIN TAB_ENUM B ON B.RN = A.RN - 1 
ORDER BY A.ENGSTME;

Результат:

|ENGSTME            |ENGSTME_PREV       |TS_DURATION   |TS_DIFF_SEC|
|-------------------|-------------------|--------------|-----------|
|2020-02-17 09:46:19|                   |              |           |
|2020-02-17 09:46:29|2020-02-17 09:46:19|00000000000010|10         |
|2020-02-17 09:50:10|2020-02-17 09:46:29|00000000000341|221        |
|2020-02-17 10:01:11|2020-02-17 09:50:10|00000000001101|661        |
|2020-02-17 10:12:16|2020-02-17 10:01:11|00000000001105|665        |
|2020-02-17 11:10:17|2020-02-17 10:12:16|00000000005801|3481       |

Идея состоит в том, сначала перечислить строки, а затем снова объединить строки, чтобы получить предыдущую временную метку в дополнительном столбце для текущей строки. Вы можете сделать такое перечисление для каждой группы (если есть), а не для всего набора данных, как в примере (добавьте соответствующее предложение PARTITION BY внутри OVER в начале и столбцы такой группы в JOIN).
Вы можете использовать TS_DURATION столбец или использовать свой собственный расчет на TS_DIFF_SEC, чтобы получить дополнительные столбцы, которые вы хотите.

Пожалуйста, предоставьте точный желаемый результат в данных этого образца, если вы этого не хотите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...