[英]Filtering between dates Oracle SQL Developer
我正在運行此查詢以查看兩個日期之間的數據,如下面的代碼所示,但是我僅獲取當前日期(如果日期是連續的)或日期間隔前一天的數據。
我的意思是:
如果間隔(16/05/18-17/05/18)僅返回16/05/18的數據。
如果interval為(16/05/18-18/05/18)僅返回interval(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';
您正在將列值與字符串值進行比較,這意味着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()
,使用合適的顯式格式掩碼。 我建議您還是使用完整的四位數年份,而不是兩位數,這仍然會引起混淆(特別是在隱式轉換的情況下,但也容易顯式地出錯...)
我建議您在句子C.CALLTIMESTAMP之間使用'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 BETWEEN '16/05/18' AND '17/05/18 11:59:59,000000000 PM';
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.