Oracle查询,按小时获取记录数
Oracle query, get count of records by hour
我正在尝试获取每小时的交易计数。通常这是一个直接的查询,不幸的是我必须使用的时间戳列不是时间戳而是 varchar2!无论我尝试什么,我都会得到“无效月份”或“无效数字”,具体取决于我使用的格式。
时间戳看起来像:2021-08-08 00:00:52:632
我还执行了以下命令来获取 NLS 格式:
SELECT * FROM nls_session_parameters WHERE parameter = 'NLS_DATE_FORMAT';
并获得
DD-MON-RRRR.
这是我在其他十几个中尝试过的最新一个(我注释掉了“group by”只是为了显示该死的东西)。
select to_char(reqts,'mm/dd/yyyy hh24') DATE_HR
--, count(*)
from idcreqresplog
where logdate > trunc(SYSDATE -2)
and logtypeid in (2,4)
--group by to_char(reqts,'mm/dd/yyyy hh24');
还有
select to_char(reqts, 'yyyy-mm-dd hh24:mi:ss.fff' )
--, count(*)
FROM
reqresplog
WHERE
logdate > trunc(SYSDATE -2) ;
--group by to_date(reqts, 'yyyy-mm-dd HH4');
我束手无策,需要一些帮助。
假设如 LittleFoot 所建议的那样,您的某些数据是错误的,您可以使用内联 WITH 函数来根除错误数据。举个例子:
WITH FUNCTION get_timestamp
(
p_sTimeString VARCHAR2
)
RETURN TIMESTAMP
IS
BEGIN
RETURN TO_TIMESTAMP(p_sTimeString, 'YYYY-MM-DD HH24:MI:SS.FF3');
EXCEPTION WHEN OTHERS THEN RETURN NULL;
END;
SELECT TO_CHAR(s.hour, 'YYYY-MM-DD HH24') AS HOUR, COUNT(*) AS ROW_COUNT
FROM (SELECT TRUNC(get_timestamp(td.time), 'HH24') AS HOUR,
td.amount
FROM test_data td) s
WHERE s.hour IS NOT NULL
GROUP BY s.hour
ORDER BY s.hour;
这里是 DBFiddle,显示了它对一些好数据和坏数据的工作情况 (Link)。
查询所做的是使用内联函数调用 TO_TIMESTAMP
函数。然后它只捕获任何错误和 returns NULL
。这可以避免您的不良数据弄乱您的查询。之后,查询与您之前尝试的几乎一样。我在内部查询中将时间戳截断为小时,然后在外部查询中使用它进行分组(仅使用没有 NULL
时间戳的行......这意味着它们没有错误)
假设您的列始终采用 2021-08-08 00:00:52:63
格式,然后将子字符串分组到第 13 个字符:
SELECT SUBSTR(reqts, 1, 13) AS date_hr,
count(*)
FROM idcreqresplog
WHERE logdate > trunc(SYSDATE -2)
AND logtypeid in (2,4)
GROUP BY
SUBSTR(reqts, 1, 13);
如果您确实想转换为日期,那么从 Oracle 12.2 开始,您可以使用 TO_TIMESTAMP(string_value DEFAULT NULL ON CONVERSION ERROR, 'YYYY-MM-DD HH24:MI:SS:FF')
:
SELECT TRUNC(
TO_TIMESTAMP(
reqts DEFAULT NULL ON CONVERSION ERROR,
'YYYY-MM-DD HH24:MI:SS:FF'
),
'HH'
) AS date_hr,
COUNT(*)
FROM idcreqresplog
WHERE logdate > trunc(SYSDATE -2)
AND logtypeid in (2,4)
GROUP BY
TRUNC(
TO_TIMESTAMP(
reqts DEFAULT NULL ON CONVERSION ERROR,
'YYYY-MM-DD HH24:MI:SS:FF'
),
'HH'
)
db<>fiddle here
我正在尝试获取每小时的交易计数。通常这是一个直接的查询,不幸的是我必须使用的时间戳列不是时间戳而是 varchar2!无论我尝试什么,我都会得到“无效月份”或“无效数字”,具体取决于我使用的格式。
时间戳看起来像:2021-08-08 00:00:52:632
我还执行了以下命令来获取 NLS 格式:
SELECT * FROM nls_session_parameters WHERE parameter = 'NLS_DATE_FORMAT';
并获得
DD-MON-RRRR.
这是我在其他十几个中尝试过的最新一个(我注释掉了“group by”只是为了显示该死的东西)。
select to_char(reqts,'mm/dd/yyyy hh24') DATE_HR
--, count(*)
from idcreqresplog
where logdate > trunc(SYSDATE -2)
and logtypeid in (2,4)
--group by to_char(reqts,'mm/dd/yyyy hh24');
还有
select to_char(reqts, 'yyyy-mm-dd hh24:mi:ss.fff' )
--, count(*)
FROM
reqresplog
WHERE
logdate > trunc(SYSDATE -2) ;
--group by to_date(reqts, 'yyyy-mm-dd HH4');
我束手无策,需要一些帮助。
假设如 LittleFoot 所建议的那样,您的某些数据是错误的,您可以使用内联 WITH 函数来根除错误数据。举个例子:
WITH FUNCTION get_timestamp
(
p_sTimeString VARCHAR2
)
RETURN TIMESTAMP
IS
BEGIN
RETURN TO_TIMESTAMP(p_sTimeString, 'YYYY-MM-DD HH24:MI:SS.FF3');
EXCEPTION WHEN OTHERS THEN RETURN NULL;
END;
SELECT TO_CHAR(s.hour, 'YYYY-MM-DD HH24') AS HOUR, COUNT(*) AS ROW_COUNT
FROM (SELECT TRUNC(get_timestamp(td.time), 'HH24') AS HOUR,
td.amount
FROM test_data td) s
WHERE s.hour IS NOT NULL
GROUP BY s.hour
ORDER BY s.hour;
这里是 DBFiddle,显示了它对一些好数据和坏数据的工作情况 (Link)。
查询所做的是使用内联函数调用 TO_TIMESTAMP
函数。然后它只捕获任何错误和 returns NULL
。这可以避免您的不良数据弄乱您的查询。之后,查询与您之前尝试的几乎一样。我在内部查询中将时间戳截断为小时,然后在外部查询中使用它进行分组(仅使用没有 NULL
时间戳的行......这意味着它们没有错误)
假设您的列始终采用 2021-08-08 00:00:52:63
格式,然后将子字符串分组到第 13 个字符:
SELECT SUBSTR(reqts, 1, 13) AS date_hr,
count(*)
FROM idcreqresplog
WHERE logdate > trunc(SYSDATE -2)
AND logtypeid in (2,4)
GROUP BY
SUBSTR(reqts, 1, 13);
如果您确实想转换为日期,那么从 Oracle 12.2 开始,您可以使用 TO_TIMESTAMP(string_value DEFAULT NULL ON CONVERSION ERROR, 'YYYY-MM-DD HH24:MI:SS:FF')
:
SELECT TRUNC(
TO_TIMESTAMP(
reqts DEFAULT NULL ON CONVERSION ERROR,
'YYYY-MM-DD HH24:MI:SS:FF'
),
'HH'
) AS date_hr,
COUNT(*)
FROM idcreqresplog
WHERE logdate > trunc(SYSDATE -2)
AND logtypeid in (2,4)
GROUP BY
TRUNC(
TO_TIMESTAMP(
reqts DEFAULT NULL ON CONVERSION ERROR,
'YYYY-MM-DD HH24:MI:SS:FF'
),
'HH'
)
db<>fiddle here