SQL查询以查找失败之间的成功次数

标签 sql oracle oracle11g

我有一个包含测试结果记录的 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/

相关文章:

MySQL:按值对记录进行计数,然后用其计数更新另一列

Oracle产品版本和jdbc驱动版本?

oracle - "ORA-12571: TNS packet writer failure"和 "ORA-03135: connection lost contact"和有什么区别?

ORACLE 11G UTL_FILE + UTL_FILE_DIR - 无效目录

sql - ORA-00942 未创建 oracle 中的 EXECUTE IMMEDIATE 临时表

java - JMS 与 Hibernate session

mysql - sql distinct,得到2列

java - 在Java中将变量添加到sql语句中

sql - CREATE AS SELECT * 但使用从另一个表获取的一列

python - sqlalchemy 选择 to_date