我有一个包含测试结果记录的 oracle 数据库表。每条记录都包含测试 START_TIME、执行测试的 INSTRUMENT 和 ERROR_CODE(如果在测试期间发生错误)以及其他信息。
对于 ERROR_CODE 等于“5900”、“6900”或“5905”的每条记录,我需要确定在错误记录的日期时间之前在该仪器上发生的成功测试(ERROR_CODE = null)的数量.换句话说,我需要知道在生成错误之前在仪器上执行的成功测试的数量。
数据库包含 500 多台仪器,每台仪器可以有 1 到 500,000 条测试记录。
注意:只对 ERROR_CODES '5900'、'6000' 和 '5905' 之前的成功次数感兴趣。有些仪器的这些错误可能为零。一些仪器可能有多个连续的错误,它们之间没有成功。该仪器的第一次或最后一次测试可能发生了错误。
例子:
START_TIME INSTRUMENT ERROR_CODE
12/1/2015 22:15:03 A540 null
12/1/2015 22:17:14 A700 null
12/1/2015 22:17:53 A700 null
12/1/2015 22:19:24 A700 5905
12/1/2015 23:28:15 A700 null
12/1/2015 23:35:10 A540 6000
12/2/2015 02:15:13 A540 5900
12/2/2015 03:07:03 A540 null
12/2/2015 03:44:52 A540 null
12/2/2015 09:15:56 A700 null
12/2/2015 14:17:09 A700 5900
12/2/2015 17:15:42 A980 null
12/3/2015 08:17:53 A540 5900
12/3/2015 08:18:49 A540 5900
12/3/2015 11:17:57 A540 null
应该给出以下结果
ERROR_TIME INSTRUMENT SUCCESSES_BEFORE_ERROR
12/1/2015 22:19:24 A700 2
12/1/2015 23:35:10 A540 1
12/2/2015 02:15:13 A540 1
12/2/2015 14:17:09 A700 4
12/3/2015 08:17:53 A540 3
12/3/2015 08:18:49 A540 3
最佳答案
下面是一种使用解析函数的方法:
WITH test_results AS (SELECT to_date('12/01/2015 22:15:03', 'mm/dd/yyyy hh24:mi:ss') start_time, 'A540' instrument, NULL ERROR_CODE FROM dual UNION ALL
SELECT to_date('12/01/2015 22:17:14', 'mm/dd/yyyy hh24:mi:ss') start_time, 'A700' instrument, NULL ERROR_CODE FROM dual UNION ALL
SELECT to_date('12/01/2015 22:17:53', 'mm/dd/yyyy hh24:mi:ss') start_time, 'A700' instrument, NULL ERROR_CODE FROM dual UNION ALL
SELECT to_date('12/01/2015 22:19:24', 'mm/dd/yyyy hh24:mi:ss') start_time, 'A700' instrument, 5905 ERROR_CODE FROM dual UNION ALL
SELECT to_date('12/01/2015 23:28:15', 'mm/dd/yyyy hh24:mi:ss') start_time, 'A700' instrument, NULL ERROR_CODE FROM dual UNION ALL
SELECT to_date('12/01/2015 23:35:10', 'mm/dd/yyyy hh24:mi:ss') start_time, 'A540' instrument, 6000 ERROR_CODE FROM dual UNION ALL
SELECT to_date('12/02/2015 02:15:13', 'mm/dd/yyyy hh24:mi:ss') start_time, 'A540' instrument, 5900 ERROR_CODE FROM dual UNION ALL
SELECT to_date('12/02/2015 03:07:03', 'mm/dd/yyyy hh24:mi:ss') start_time, 'A540' instrument, NULL ERROR_CODE FROM dual UNION ALL
SELECT to_date('12/02/2015 03:44:52', 'mm/dd/yyyy hh24:mi:ss') start_time, 'A540' instrument, NULL ERROR_CODE FROM dual UNION ALL
SELECT to_date('12/02/2015 09:15:56', 'mm/dd/yyyy hh24:mi:ss') start_time, 'A700' instrument, NULL ERROR_CODE FROM dual UNION ALL
SELECT to_date('12/02/2015 14:17:09', 'mm/dd/yyyy hh24:mi:ss') start_time, 'A700' instrument, 5900 ERROR_CODE FROM dual UNION ALL
SELECT to_date('12/02/2015 17:15:42', 'mm/dd/yyyy hh24:mi:ss') start_time, 'A980' instrument, NULL ERROR_CODE FROM dual UNION ALL
SELECT to_date('12/03/2015 08:17:53', 'mm/dd/yyyy hh24:mi:ss') start_time, 'A540' instrument, 5900 ERROR_CODE FROM dual UNION ALL
SELECT to_date('12/03/2015 08:18:49', 'mm/dd/yyyy hh24:mi:ss') start_time, 'A540' instrument, 5900 ERROR_CODE FROM dual UNION ALL
SELECT to_date('12/03/2015 11:17:57', 'mm/dd/yyyy hh24:mi:ss') start_time, 'A540' instrument, NULL ERROR_CODE FROM dual)
-- end of mimicking a table with data in it called "test_results"
-- for use in the following select statement:
SELECT start_time,
instrument,
running_total success_before_error
FROM (SELECT start_time,
instrument,
ERROR_CODE,
sum(CASE WHEN ERROR_CODE IS NOT NULL THEN 0
ELSE 1
END) OVER (PARTITION BY instrument ORDER BY start_time) running_total
FROM test_results)
WHERE ERROR_CODE IS NOT NULL -- this may need to be "error_code in (5900, 6000, 5905)"
ORDER BY start_time;
START_TIME INSTRUMENT SUCCESS_BEFORE_ERROR
------------------- ---------- --------------------
12/01/2015 22:19:24 A700 2
12/01/2015 23:35:10 A540 1
12/02/2015 02:15:13 A540 1
12/02/2015 14:17:09 A700 4
12/03/2015 08:17:53 A540 3
12/03/2015 08:18:49 A540 3
关于SQL查询以查找失败之间的成功次数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40346246/