简体   繁体   English

DB2 SQL 添加列值

[英]DB2 SQL Adding Columns Values

I am trying to add some calculated columns together where the values from those columns are substrings of a timestamp difference function between the current record and the next record.我正在尝试将一些计算列添加在一起,其中来自这些列的值是当前记录和下一条记录之间时间戳差异函数的子字符串。 Unfortunately the substring does return null values and I have attempted to convert these via the COALESCE, ISNULL and I am not getting anywhere with this in order to get these values to add properly.不幸的是,子字符串确实返回了空值,我试图通过 COALESCE、ISNULL 来转换这些值,但为了正确添加这些值,我没有得到任何帮助。 I have also attempted the SUM function but i am getting error on that as well.我也尝试过 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%' 

I am trying to add the columns labeled as DAYS, HOURS, MINUTES, SECONDS so what would be the correct way to accomplish this?我正在尝试添加标记为 DAYS、HOURS、MINUTES、SECONDS 的列,那么完成此操作的正确方法是什么?

Sample Data Below下面的示例数据

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

I'm not sure but it seems that it's V7.1.我不确定,但似乎是 V7.1。
Try this as is:试试这个:

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;

The result is:结果是:

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

The idea is to enumerate the rows first, and then rejoin rows to get previous timestamp in an additional column for a current row.这个想法是首先枚举行,然后重新加入行以获取当前行的附加列中的先前时间戳。 You may do such an enumeration for each group (if any), and not for the entire data set as in the example (add the corresponding PARTITION BY clause inside OVER at the beginning and the columns of such a group in JOIN ).您可以对每个组(如果有)进行这样的枚举,而不是像示例中那样对整个数据集进行枚举(在OVER开头添加相应的PARTITION BY子句,并在JOIN中添加此类组的列)。
You may use TS_DURATION column or use your own calculation on TS_DIFF_SEC to get additional columns you want.您可以使用TS_DURATION列或在TS_DIFF_SEC上使用您自己的计算来获得您想要的其他列。

Please, provide the exact result desired on this sample data, If this is not you want.请提供此示例数据所需的确切结果,如果这不是您想要的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM