我有一个包含错误代码和输入时间(以及其他内容)的表格 我需要的是一种方法来计算最后一小时具有相同错误代码(我选择)的行数,并将结果与错误代码串起来。
SELECT COUNT(*) || ',' || error_code as amount_and_code
FROM my_table
WHERE error_code in (5001, 5002, 5003, 5004, 5005)
AND entry_date >= (SYSDATE - 1/24)
group by error_code;
我得到了
的明显结果AMOUNT_AND_CODE
---------------
4,5001
1,5002
2,5005
我的问题是:如何为未找到的值返回0,error_code
我想得到的是
AMOUNT_AND_CODE
---------------
4,5001
1,5002
0,5003
0,5004
2,5005
有没有办法获得我正在寻找的输出?
非常感谢你的帮助,mod。
编辑:我没有包含所有错误代码的表格 Edit2:Oracle8i企业版8.1.7.4.0版
答案 0 :(得分:5)
您可以尝试这样的事情:
SQL> create table nnn(error_code varchar2(4), entry_date date);
Table created.
SQL> insert into nnn values (5001, sysdate);
1 row created.
SQL> insert into nnn values (5003, sysdate - 10);
1 row created.
SQL>
SQL> with tbl as
2 (select 5001 error_code from dual union all
3 select 5002 error_code from dual union all
4 select 5003 error_code from dual union all
5 select 5004 error_code from dual)
6 select count(nnn.error_code), tbl.error_code
7 from nnn, tbl
8 where nnn.error_code(+) = tbl.error_code
9 and entry_date(+) >= (SYSDATE - 1/24)
10 group by tbl.error_code;
COUNT(NNN.ERROR_CODE) ERROR_CODE
--------------------- ----------
0 5003
1 5001
0 5002
0 5004
SQL>
答案 1 :(得分:4)
你有错误代码表吗?如果是这样,那么你可以这样做:
SELECT COUNT(my_table.id) || ',' || e.error_code as amount_and_code
FROM error_codes e
LEFT OUTER JOIN my_table ON my_table.error_code = e.error_code
AND my_table.entry_date >= (SYSDATE - 1/24)
WHERE e.error_code in (5001, 5002, 5003, 5004, 5005)
group by e.error_code;
如果没有,请尝试:
WITH error_codes as
( SELECT 5001 FROM DUAL
UNION ALL
SELECT 5002 FROM DUAL
UNION ALL
SELECT 5003 FROM DUAL
UNION ALL
SELECT 5004 FROM DUAL
UNION ALL
SELECT 5005 FROM DUAL
)
SELECT COUNT(my_table.id) || ',' || e.error_code as amount_and_code
FROM error_codes e
LEFT OUTER JOIN my_table ON my_table.error_code = e.error_code
AND my_table.entry_date >= (SYSDATE - 1/24)
group by e.error_code;
答案 2 :(得分:2)
你试过......
SELECT NVL (COUNT(*), 0) || ',' || error_code as amount_and_code
FROM my_table
WHERE error_code in (5001, 5002, 5003, 5004, 5005) AND
entry_date >= (SYSDATE - 1/24)
GROUP BY error_code;
答案 3 :(得分:2)
错误代码是否总是按顺序排列?在这种情况下,您应该能够使用连接:
SELECT COUNT(MY_TABLE.ERROR_CODE) || ',' || ERROR_CODES.error_code as amount_and_code
FROM
(
SELECT (5000+LEVEL) error_code
FROM DUAL
CONNECT BY LEVEL <= 5
) ERROR_CODES
LEFT JOIN
(
SELECT 5001 ERROR_CODE, (SYSDATE - 1/26) ENTRY_DATE FROM DUAL
UNION ALL
SELECT 5001 ERROR_CODE, (SYSDATE - 1/26) ENTRY_DATE FROM DUAL
union all
SELECT 5001 ERROR_CODE, (SYSDATE - 1/26) ENTRY_DATE FROM DUAL
union all
SELECT 5001 ERROR_CODE, (SYSDATE - 1/26) ENTRY_DATE FROM DUAL
union all
SELECT 5002 ERROR_CODE, (SYSDATE - 1/26) ENTRY_DATE FROM DUAL
union all
SELECT 5005 ERROR_CODE, (SYSDATE - 1/26) ENTRY_DATE FROM DUAL
UNION all
SELECT 5005 ERROR_CODE, (SYSDATE - 1/26) ENTRY_DATE FROM DUAL
) MY_TABLE
ON MY_TABLE.ERROR_CODE = ERROR_CODES.ERROR_CODE
AND MY_TABLE.ENTRY_DATE >= (SYSDATE - 1/24)
GROUP BY ERROR_CODES.ERROR_CODE
order by ERROR_CODES.error_code
;
如果您只想显示所有错误,可以尝试使用
with MY_TABLE as(
SELECT 5001 ERROR_CODE, (SYSDATE - 1/26) ENTRY_DATE FROM DUAL
UNION ALL
SELECT 5001 ERROR_CODE, (SYSDATE - 1/26) ENTRY_DATE FROM DUAL
union all
SELECT 5001 ERROR_CODE, (SYSDATE - 1/26) ENTRY_DATE FROM DUAL
union all
SELECT 5001 ERROR_CODE, (SYSDATE - 1/26) ENTRY_DATE FROM DUAL
union all
SELECT 5002 ERROR_CODE, (SYSDATE - 1/26) ENTRY_DATE FROM DUAL
union all
SELECT 5005 ERROR_CODE, (SYSDATE - 1/26) ENTRY_DATE FROM DUAL
UNION ALL
SELECT 5005 ERROR_CODE, (SYSDATE - 1/26) ENTRY_DATE FROM DUAL
UNION ALL
SELECT 5003 ERROR_CODE, (SYSDATE - 1/23) ENTRY_DATE FROM DUAL
UNION ALL
SELECT 5004 ERROR_CODE, (SYSDATE - 1/23) ENTRY_DATE FROM DUAL
UNION ALL
SELECT 5006 ERROR_CODE, (SYSDATE - 1/23) ENTRY_DATE FROM DUAL
UNION ALL
SELECT 5010 ERROR_CODE, (SYSDATE - 1/23) ENTRY_DATE FROM DUAL
UNION ALL
SELECT 6018 ERROR_CODE, (SYSDATE - 1/23) ENTRY_DATE FROM DUAL
)
SELECT COUNT(MY_TABLE.ERROR_CODE) || ',' || ERROR_CODES.error_code as amount_and_code
FROM
(
SELECT DISTINCT ERROR_CODE
FROM MY_TABLE --**warning** this could be resource intensive
) ERROR_CODES
LEFT JOIN
MY_TABLE
ON MY_TABLE.ERROR_CODE = ERROR_CODES.ERROR_CODE
AND MY_TABLE.ENTRY_DATE >= (SYSDATE - 1/24)
GROUP BY ERROR_CODES.ERROR_CODE
order by ERROR_CODES.error_code
;
这实际上只是让您对表格中的所有错误代码进行区分,然后根据时间选择计数
(
SELECT DISTINCT ERROR_CODE
FROM MY_TABLE --**warning** this could be resource intensive
) ERROR_CODES
请注意,这可能是资源密集型的
如果你只想要特定的数字(即5001,5002,5003,####,#### 2,...,### x)那么你可以试试这样的东西(这需要一个自定义类型和要创建的函数):
--see http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:210612357425
--create a table of numbers ,create a function to split the "where" into a table
--then return the data
CREATE OR REPLACE type numberTableType as table of number;
/
create or replace function in_number( p_string in varchar2 ) return numberTableType AS
l_string long default p_string || ',';
l_data numberTableType := numberTableType();
l_number number ;
N NUMBER;
BEGIN
loop
exit when l_string is null;
n := instr( l_string, ',' );
l_data.extend;
begin --is user inputs a non-numeric value skip the value
l_number := cast(ltrim( rtrim( substr( l_string, 1, n-1 ) ) ) as number);
l_data(l_data.count) := l_number ;
EXCEPTION
WHEN VALUE_ERROR THEN
l_number := 0;
WHEN OTHERS THEN
raise ;
end ;
l_string := substr( l_string, n+1 );
end loop;
RETURN L_DATA;
END in_number;
/
SELECT COUNT(MY_TABLE.ERROR_CODE) || ',' || ERROR_CODES.error_code as amount_and_code
FROM
(
SELECT COLUMN_VALUE AS ERROR_CODE
from table(in_number('5001,5002,5003,5004,5005,5010'))
) ERROR_CODES
LEFT JOIN
(
SELECT 5001 ERROR_CODE, (SYSDATE - 1/26) ENTRY_DATE FROM DUAL
UNION ALL
SELECT 5001 ERROR_CODE, (SYSDATE - 1/26) ENTRY_DATE FROM DUAL
union all
SELECT 5001 ERROR_CODE, (SYSDATE - 1/26) ENTRY_DATE FROM DUAL
union all
SELECT 5001 ERROR_CODE, (SYSDATE - 1/26) ENTRY_DATE FROM DUAL
union all
SELECT 5002 ERROR_CODE, (SYSDATE - 1/26) ENTRY_DATE FROM DUAL
union all
SELECT 5005 ERROR_CODE, (SYSDATE - 1/26) ENTRY_DATE FROM DUAL
UNION ALL
SELECT 5005 ERROR_CODE, (SYSDATE - 1/26) ENTRY_DATE FROM DUAL
UNION ALL
SELECT 5003 ERROR_CODE, (SYSDATE - 1/23) ENTRY_DATE FROM DUAL
UNION ALL
SELECT 5004 ERROR_CODE, (SYSDATE - 1/23) ENTRY_DATE FROM DUAL
UNION ALL
SELECT 5006 ERROR_CODE, (SYSDATE - 1/23) ENTRY_DATE FROM DUAL
UNION ALL
SELECT 5010 ERROR_CODE, (SYSDATE - 1/23) ENTRY_DATE FROM DUAL
UNION ALL
SELECT 6018 ERROR_CODE, (SYSDATE - 1/23) ENTRY_DATE FROM DUAL
)
MY_TABLE
ON MY_TABLE.ERROR_CODE = ERROR_CODES.ERROR_CODE
AND MY_TABLE.ENTRY_DATE >= (SYSDATE - 1/24)
GROUP BY ERROR_CODES.ERROR_CODE
ORDER BY ERROR_CODES.ERROR_CODE
;
答案 4 :(得分:2)
我希望entry_date >= (SYSDATE - 1/24)
过滤您需要的记录(即5003&amp; 5004)。
删除该条件并检查结果。
或
尝试以下查询,它可以解决您的问题
SELECT COUNT(error_code) || ',' || error_code as amount_and_code
FROM my_table
WHERE error_code in (5001, 5002, 5003, 5004, 5005) AND
entry_date >= (SYSDATE - 1/24)
GROUP BY error_code;
答案 5 :(得分:1)
提出一个请求,就好像你有一个extern表,没有在Oracle 8中没有'WITH'... 与Tony的代码非常相似:
SELECT COUNT(t1.error_code) || ',' || t2.error_code as amount_and_code
FROM my_table t right outer join
(
select 5001 as error_code from dual
union
select 5002 as error_code from dual
union
select 5003 as error_code from dual
union
select 5004 as error_code from dual
union
select 5005 as error_code from dual
) t2 on t1.error_code = t2.error_code
and t.entry_date >= (SYSDATE - 1/24)
group by t2.error_code;
答案 6 :(得分:0)
您是否有一个列出错误代码的主表?如果是这样,我会外连接到该表,以便保证为每个条目返回一行。