Фильтрация между датами Oracle SQL Developer - PullRequest
0 голосов
/ 17 мая 2018

Я выполняю этот запрос для просмотра данных между двумя датами, как показано в коде ниже, но я получаю данные только о текущей дате (если даты идут подряд) или за день до этого, если есть интервал дат.

Я имею в виду:

  • если интервал (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 голосов
/ 17 мая 2018

Вы сравниваете значения столбцов со строковыми значениями, что означает, что 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(), используя подходящую явную маску формата. В любом случае, я бы порекомендовал вам использовать полные четырехзначные годы, а не двухзначные, что может привести к путанице (особенно при неявном преобразовании, но также легко легко ошибиться ...)

0 голосов
/ 17 мая 2018

Спасибо всем, я выбрал легкий путь

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';
0 голосов
/ 17 мая 2018

Я рекомендую вам использовать МЕЖДУ предложением C.CALLTIMESTAMP МЕЖДУ '16 / 05/18 'И '17 / 05/18';

Надеюсь, вы помогли.

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