在Oracle SQL Developer的日期之间过滤

时间:2018-05-17 15:59:17

标签: sql oracle

我正在运行此查询以查看两个日期之间的数据,如下面的代码所示,但我只获取当前日期的数据(如果日期是连续的)或前一天的数据,如果有一个日期间隔。

我的意思是:

  • 如果间隔(16/05/18 - 17/05/18)仅返回16/05/18的数据。

  • 如果间隔为(16/05/18 - 18/05/18),则仅返回间隔数据(16/05/18 - 17/05/18)

代码:

SELECT 
    C.SESSIONID,
    SUBSTR(C.ORIGINATINGNUMBER, INSTR(C.ORIGINATINGNUMBER, ':') + 1,
           INSTR(C.ORIGINATINGNUMBER, '@') - INSTR(C.ORIGINATINGNUMBER, ':') - 1) AS Origen,
    TO_CHAR(C.CALLTIMESTAMP, 'DD/MM/YYYY') AS Fecha,
    TO_CHAR(C.CALLTIMESTAMP,'HH:MI') AS Hora,
    C.DURATION AS Duracion_IVR,
    (CASE C.ENDTYPE
        WHEN 1
           THEN 'IVR'
        WHEN 2
           THEN 'Transferida'
        ELSE 'Colgada'
     END) AS Estado,
     A.SERVICIO,
     A.OPT,
     A.CONTRATO_ENVIADO,
     A.RPTA_WS_C,
     A.RPTA_WS_L,
     A.DESCRIPTIVO
 FROM 
     CDR C
 JOIN
     (SELECT DISTINCT(D.SESSIONID) AS ID,
    NVL(
    (SELECT B.MESSAGE
    FROM VPAPPLOG B
    WHERE D.SESSIONID  = B.SESSIONID
    AND B.ACTIVITYNAME = 'CAMP'
    ),' ') AS SERVICIO,
    NVL(
    (SELECT B.ACTIVITYNAME
    FROM VPAPPLOG B
    WHERE D.SESSIONID = B.SESSIONID
    AND B.MESSAGE     = 'OPC_MENU'
    ),' ') AS OPT,
    NVL(
    (SELECT B.VARVALUE
    FROM VPAPPLOG B
    WHERE D.SESSIONID = B.SESSIONID
    AND B.VARNAME     = 'CONT_ENV'
    ),' ') AS CONTRATO_ENVIADO,
    NVL(
    (SELECT B.VARVALUE
    FROM VPAPPLOG B
    WHERE D.SESSIONID  = B.SESSIONID
    AND B.VARNAME      = 'COD_RSLT_OPER'
    AND B.ACTIVITYNAME = '000'
    ),' ') AS RPTA_WS_C,
    NVL(
    (SELECT B.VARVALUE
    FROM VPAPPLOG B
    WHERE D.SESSIONID  = B.SESSIONID
    AND B.VARNAME      = 'COD_RSLT_OPER'
    AND B.ACTIVITYNAME = '001'
    ),' ') AS RPTA_WS_L,
    NVL(
    (SELECT B.VARVALUE
    FROM VPAPPLOG B
    WHERE D.SESSIONID  = B.SESSIONID
    AND B.ACTIVITYNAME = 'MSG_RPTA'
    ),' ') AS DESCRIPTIVO
  FROM VPAPPLOG D
  ) A
ON A.ID = C.SESSIONID
WHERE C.APPLICATIONNAME = 'IVR_AGBAR_Dllo'
AND C.CALLTIMESTAMP >= '16/05/18' AND C.CALLTIMESTAMP <= '17/05/18';

3 个答案:

答案 0 :(得分:2)

您正在将列值与字符串值进行比较,这意味着Oracle使用会话NLS设置将字符串隐式转换为日期或时间戳。您可以从执行计划的过滤步骤中看到:

   1 - filter("C"."CALLTIMESTAMP">=TO_TIMESTAMP('16/05/18') AND 
              "C"."CALLTIMESTAMP"<=TO_TIMESTAMP('17/05/18'))

这些隐式转换的值将时间组件设置为午夜。 (它们也非常脆弱,因为它们依赖于您使用的匹配会话设置的字符串,并不总是在您的控制之下。)

这意味着您正在寻找2018-05-16 00:00:00和2018-05-17 00:00:00之间的值。这将在16日的任何时间捕获值,但只会在17日找到正好在午夜的记录。

执行此操作的常用方法是使用大于或等于开始日期的范围,小于 结束日期之后的日期 - 这意味着您抓住了每一天,但不包括当天的午夜。

AND C.CALLTIMESTAMP >= timestamp '2018-05-16 00:00:00'
AND C.CALLTIMESTAMP < timestamp '2018-05-18 00:00:00'

可以在16日或17日随时查找所有记录。

如果列实际上是日期而不是时间戳,那么您可以改为使用日期文字:

AND C.CALLTIMESTAMP >= date '2018-05-16'
AND C.CALLTIMESTAMP < date '2018-05-18';

如果您不想使用文字,可以使用to_date()to_timestamp(),使用合适的显式格式掩码。我建议你使用完整的四位数年份,而不是2位数,这仍然会引起混淆(特别是隐式转换,但也很容易明白错误......)

答案 1 :(得分:0)

我建议您使用BETWEEN句子 C.CALLTIMESTAMP BETWEEN&#39; 16/05/18&#39;和&#39; 17/05/18&#39;;

我希望能帮到你。

答案 2 :(得分:0)

谢谢大家,我采取了轻松的方式

SELECT C.SESSIONID,
  SUBSTR(C.ORIGINATINGNUMBER,INSTR(C.ORIGINATINGNUMBER, ':') + 1,INSTR(C.ORIGINATINGNUMBER, '@') - INSTR(C.ORIGINATINGNUMBER, ':') - 1) AS Origen,
  TO_CHAR(C.CALLTIMESTAMP,'DD/MM/YYYY')                                                                                              AS Fecha,
  TO_CHAR(C.CALLTIMESTAMP,'HH:MI')                                                                                                   AS Hora,
  C.DURATION                                                                                                                         AS Duracion_IVR,
  (
  CASE C.ENDTYPE
    WHEN 1
    THEN 'IVR'
    WHEN 2
    THEN 'Transferida'
    ELSE 'Colgada'
  END) AS Estado,
  A.SERVICIO,
  A.OPT,
  A.CONTRATO_ENVIADO,
  A.RPTA_WS_C,
  A.RPTA_WS_L,
  A.DESCRIPTIVO
FROM CDR C
JOIN
  (SELECT DISTINCT(D.SESSIONID) AS ID,
    NVL(
    (SELECT B.MESSAGE
    FROM VPAPPLOG B
    WHERE D.SESSIONID  = B.SESSIONID
    AND B.ACTIVITYNAME = 'CAMP'
    ),' ') AS SERVICIO,
    NVL(
    (SELECT B.ACTIVITYNAME
    FROM VPAPPLOG B
    WHERE D.SESSIONID = B.SESSIONID
    AND B.MESSAGE     = 'OPC_MENU'
    ),' ') AS OPT,
    NVL(
    (SELECT B.VARVALUE
    FROM VPAPPLOG B
    WHERE D.SESSIONID = B.SESSIONID
    AND B.VARNAME     = 'CONT_ENV'
    ),' ') AS CONTRATO_ENVIADO,
    NVL(
    (SELECT B.VARVALUE
    FROM VPAPPLOG B
    WHERE D.SESSIONID  = B.SESSIONID
    AND B.VARNAME      = 'COD_RSLT_OPER'
    AND B.ACTIVITYNAME = '000'
    ),' ') AS RPTA_WS_C,
    NVL(
    (SELECT B.VARVALUE
    FROM VPAPPLOG B
    WHERE D.SESSIONID  = B.SESSIONID
    AND B.VARNAME      = 'COD_RSLT_OPER'
    AND B.ACTIVITYNAME = '001'
    ),' ') AS RPTA_WS_L,
    NVL(
    (SELECT B.VARVALUE
    FROM VPAPPLOG B
    WHERE D.SESSIONID  = B.SESSIONID
    AND B.ACTIVITYNAME = 'MSG_RPTA'
    ),' ') AS DESCRIPTIVO
  FROM VPAPPLOG D
  ) A
ON A.ID = C.SESSIONID
WHERE C.APPLICATIONNAME = 'IVR_AGBAR_Dllo'
AND C.CALLTIMESTAMP BETWEEN '16/05/18' AND '17/05/18 11:59:59,000000000 PM';