无法从oracle查询中的时间戳中提取分钟

时间:2014-09-09 03:03:12

标签: sql oracle plsql

我在查询中获取分钟提取的无效标识符。我在这里做错了什么?

 SELECT service_name,
         a.app_context_id,
         domain_cdc_status,
         MAX (
            (SELECT EXTRACT (minute, TO_TIMESTAMP (MAX (updated_at)))
               FROM domain_cdc
              WHERE     app_context_id = a.app_context_id
                    AND domain_cdc_status = a.domain_cdc_status
                    AND domain_cdc_status IN ('DONE', 'PENDING', 'DONE', 'NEW')))
         - MIN (
              (SELECT EXTRACT (minute, TO_TIMESTAMP ( (updated_at)))
                 FROM domain_cdc
                WHERE app_context_id = a.app_context_id
                      AND domain_cdc_status = a.domain_cdc_status
                      AND domain_cdc_status IN
                             ('DONE', 'PENDING', 'DONE', 'NEW')))
            AS diff,
         COUNT (*)
    FROM    domain_cdc a
         INNER JOIN
            application_status b
         ON a.app_context_id = b.app_context_id
   WHERE a.app_context_id IN (2334, 2333, 2332)
GROUP BY a.app_context_id, domain_cdc_status, service_name
ORDER BY 1

3 个答案:

答案 0 :(得分:0)

这不是逗号:

SELECT EXTRACT( MINUTE FROM SYSTIMESTAMP ) FROM dual

SQLFiddle:http://sqlfiddle.com/#!4/d41d8/34930

http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions050.htm

注释指出无法从DATE值中提取MINUTE。为什么?我不知道。 EXTRACT的文档不清楚。它可以从TIMESTAMP值中提取。我已经适当地改变了这个例子。

TO_TIMESTAMP不起作用的原因是因为它仅对字符数据起作用,因此您的日期首先隐式转换为VARCHAR2,然后转换为时间戳。我的猜测是你的默认日期格式的NLS设置不包括时间组件,因此中间VARCHAR2有0分钟。

假设您的updated_at列是DATE数据类型,我建议:

SELECT EXTRACT( MINUTE FROM CAST( updated_at AS TIMESTAMP )) ...

答案 1 :(得分:0)

尝试使用

SELECT service_name,
         a.app_context_id,
         domain_cdc_status,
         MAX (
            (SELECT EXTRACT (minute FROM TO_TIMESTAMP (MAX (updated_at)))
               FROM domain_cdc
              WHERE     app_context_id = a.app_context_id
                    AND domain_cdc_status = a.domain_cdc_status
                    AND domain_cdc_status IN ('DONE', 'PENDING', 'DONE', 'NEW')))
         - MIN (
              (SELECT EXTRACT (minute FROM TO_TIMESTAMP ( (updated_at)))
                 FROM domain_cdc
                WHERE app_context_id = a.app_context_id
                      AND domain_cdc_status = a.domain_cdc_status
                      AND domain_cdc_status IN
                             ('DONE', 'PENDING', 'DONE', 'NEW')))
            AS diff,
         COUNT (*)
    FROM    domain_cdc a
         INNER JOIN
            application_status b
         ON a.app_context_id = b.app_context_id
   WHERE a.app_context_id IN (2334, 2333, 2332)
GROUP BY a.app_context_id, domain_cdc_status, service_name
ORDER BY 1

此外,您的字段update_at应为时间戳类型,因为SELECT EXTRACT( MINUTE FROM to_timestamp(sysdate) ) FROM dualSELECT EXTRACT( MINUTE FROM systimestamp ) FROM dual会返回不同的结果

答案 2 :(得分:0)

您没有指定您真正从此查询中寻找的内容(例如,没有“预期结果”),但您似乎希望以分钟表示的2个时间值之间存在差异。

您也没有告诉我们字段updated_at的类型。它似乎是一个约会,因为您将to_timestamp()应用于它。

因此,假设updated_at是日期类型,并且您希望以分钟表示差异,那么我建议如下:

SELECT
      service_name
    , a.app_context_id
    , domain_cdc_status
    , ( MAX(updated_at) - MIN( updated_at) ) * (24*60) AS diff /* in minutes */
    , COUNT(*)
FROM domain_cdc a
      INNER JOIN application_status b
                  ON a.app_context_id = b.app_context_id
      INNER JOIN domain_cdc c
                  ON app_context_id = a.app_context_id
                  AND domain_cdc_status = a.domain_cdc_status
                  AND domain_cdc_status IN ('DONE', 'PENDING', 'DONE', 'NEW')
WHERE a.app_context_id IN (2334, 2333, 2332)
GROUP BY
      a.app_context_id
    , domain_cdc_status
    , service_name
ORDER BY
      service_name
;