Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用SQL检索历史可用性_Sql_Oracle - Fatal编程技术网

使用SQL检索历史可用性

使用SQL检索历史可用性,sql,oracle,Sql,Oracle,我有一个历史记录表,用于存储处置性文件的可用性 该表有1000多万行 CREATE TABLE HIST_AVAILABLE_DISP ( DISP VARCHAR2(100 BYTE), STATUS CHAR(1 BYTE), DATE_CHECK DATE ) 我有一些带有处置性的表格: CREATE TABLE DISPOSITIVE ( ID INTEGER N

我有一个历史记录表,用于存储处置性文件的可用性

该表有1000多万行

CREATE TABLE HIST_AVAILABLE_DISP
(
  DISP          VARCHAR2(100 BYTE),
  STATUS        CHAR(1 BYTE),
  DATE_CHECK    DATE
)
我有一些带有处置性的表格:

CREATE TABLE DISPOSITIVE
(
  ID               INTEGER                      NOT NULL,
  ID_TYPE          INTEGER                      NOT NULL,
  DISP             VARCHAR2(100 BYTE),
  ........
)
我有一个例行程序来检查处置性文件是否可用。 如果可用,我将插入一行,其中DATE\u CHECK=sysdate,STATUS=1。如果不可用,我将插入一行,说明我检查了处置式,但没有得到响应a.k.a不可用,日期为sysdate,状态为0,HIST_available_DISP中的这两个语句都不可用

我需要得到所有已经超过24小时不可用的处置。 以下是我所做的:

SELECT 'Unavailable24h' type, id_type, disp
  FROM (SELECT   r.id_type, r.disp, MAX (h.DATE_CHECK) last_check,
                 last_availability, ROUND ((MAX (h.DATE_CHECK) - last_availability), 0) days_out
            FROM HIST_AVAILABLE_DISP h
                 INNER JOIN
                 (SELECT   disp, MAX (DATE_CHECK) last_availability
                      FROM HIST_AVAILABLE_DISP h
                     WHERE h.status = 1
                  GROUP BY disp) d ON (d.disp = h.disp)
                 INNER JOIN DISPOSITIVE r ON (h.disp = r.disp)
           WHERE r.id_type IN (1, 2)
             AND h.DATA > SYSDATE - 1
        GROUP BY r.disp, r.id_type) t1
 WHERE days_out * 24 > 24
关键是一次选择大约需要20秒。。。因为这个查询获取的是完整的表访问,正如我所说的,它有1000多万行

CREATE TABLE HIST_AVAILABLE_DISP
(
  DISP          VARCHAR2(100 BYTE),
  STATUS        CHAR(1 BYTE),
  DATE_CHECK    DATE
)
有没有办法进行更快的查询? 之后,我需要检查过去365天内所有处置品的可用性,一次统计不可用处置品的数量

编辑

假设我只有两个处置式A和B:

并从历史可用显示中选择*:

我的输出是:

Day         count_unavailable

16/02/2016  1
17/02/2016  0
18/02/2016  1
19/02/2016  0
解释清楚:

SELECT STATEMENT  ALL_ROWSCost: 16,545  Bytes: 153,66  Cardinality: 2,561                       
    10 FILTER                   
        9 HASH GROUP BY  Cost: 16,545  Bytes: 153,66  Cardinality: 2,561                
            8 HASH JOIN  Cost: 16,542  Bytes: 3.072.120  Cardinality: 51,202            
                3 VIEW USER. Cost: 9,527  Bytes: 15,929  Cardinality: 937       
                    2 HASH GROUP BY  Cost: 9,527  Bytes: 14,992  Cardinality: 937   
                        1 TABLE ACCESS FULL TABLE USER.HIST_AVAILABLE_DISP Cost: 9,168  Bytes: 80.954.416  Cardinality: 5.059.651  
                7 HASH JOIN  Cost: 7,014  Bytes: 2.201.686  Cardinality: 51,202         
                    4 TABLE ACCESS FULL TABLE USER.DISPOSITIVE Cost: 7  Bytes: 24,612  Cardinality: 879     
                    6 TABLE ACCESS BY INDEX ROWID TABLE USER.HIST_AVAILABLE_DISP Cost: 7,006  Bytes: 819,075  Cardinality: 54,605   
                        5 INDEX RANGE SCAN INDEX USER.IDX_DATA Cost: 315  Cardinality: 54,605  
谓词信息:

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter(ROUND(MAX("H"."DATE_CHECK")-"D"."DATE_CHECK",0)*24>24)
   3 - access("D"."DISP"="H"."DISP")
   6 - filter(TO_NUMBER("H"."STATUS")=1)
   7 - access("H"."DISP"="D"."DISP")
   8 - filter("D"."KEY_TYPE"= 1 AND ("D"."ID_TYPE"=1 OR "D"."ID_TYPE"=2))
  10 - access("H"."DATE_CHECK">SYSDATE@!-1)
查询-获取过去24小时内不可用的所有DISP:

查询-获取上一次不可用但发现不可用的所有DISP:

查询-检查去年的每个24小时周期:

如果要检查全天而不是24小时,请更改:

SELECT ADD_MONTHS( SYSDATE, -12 ) + LEVEL
FROM   DUAL
CONNECT BY ADD_MONTHS( SYSDATE, -12 ) + LEVEL <= SYSDATE
致:

查询-获取过去24小时内不可用的所有DISP:

查询-获取上一次不可用但发现不可用的所有DISP:

查询-检查去年的每个24小时周期:

如果要检查全天而不是24小时,请更改:

SELECT ADD_MONTHS( SYSDATE, -12 ) + LEVEL
FROM   DUAL
CONNECT BY ADD_MONTHS( SYSDATE, -12 ) + LEVEL <= SYSDATE
致:


基本上我必须得到maxdate\u状态检查=0-maxdate\u状态检查=1我很抱歉。。。刚刚编辑…0=不可用并已选中。。1=可用且已选中,我需要获取所有24小时以上不可用的处置。。但我认为有一个比我做的更好的解决方案..请运行EXPLAIN PLAN FOR SELECT。。。。。你的问题。。。然后从TableDBMS_XPLAN.Display中选择*。请将上次查询的结果复制为文本-而不是位图!!!并将其附加到问题中。谢谢。确切的期望输出:日dd/mm/yyyy-过去365天内每天不可用的计数显示..基本上我必须获得maxdate状态检查=0-maxdate状态检查=1我很抱歉。。。刚刚编辑…0=不可用并已选中。。1=可用且已选中,我需要获取所有24小时以上不可用的处置。。但我认为有一个比我做的更好的解决方案..请运行EXPLAIN PLAN FOR SELECT。。。。。你的问题。。。然后从TableDBMS_XPLAN.Display中选择*。请将上次查询的结果复制为文本-而不是位图!!!并将其附加到问题中。谢谢。确切的期望输出:日dd/mm/yyyy-过去365天内每天的不可用显示计数..嘿,谢谢你的回答。。。我正在运行更大的查询以查看返回的内容。。。但我需要得到所有24小时以上无法获得的处置。。。。。。我的第一次选择与您的查询有不同的值。。。。我看不出可用性状态=0和状态=1的日期之间的差异在哪里,为什么需要获得不同可用性的日期之间的差异才能知道它已不可用超过24小时?你只需要知道,在过去24小时内,它从未可用过,并且至少有一次不可用。我必须获得检查状态为0的最大日期和可用状态为1的最大日期,并检查差异是否大于24嘿,谢谢你的回答。。。我正在运行更大的查询以查看返回的内容。。。但我需要得到所有24小时以上无法获得的处置。。。。。。我的第一次选择与您的查询有不同的值。。。。我看不出可用性状态=0和状态=1的日期之间的差异在哪里,为什么需要获得不同可用性的日期之间的差异才能知道它已不可用超过24小时?您只需要知道,在过去24小时内,它从未可用,并且至少有一次不可用。我必须获取检查状态为0的最大日期和可用状态为1的最大日期,并检查差异是否大于24
SELECT COLUMN_VALUE AS Start_of_24hr_period,
       d.*
FROM   DISPOSITIVE d
       CROSS JOIN
       TABLE(
         CAST(
           MULTISET(
             SELECT ADD_MONTHS( SYSDATE, -12 ) + LEVEL
             FROM   DUAL
             CONNECT BY ADD_MONTHS( SYSDATE, -12 ) + LEVEL <= SYSDATE
           )
           AS SYS.ODCIDATELIST
         )
       ) y
WHERE  NOT EXISTS ( SELECT 'X'
                    FROM HIST_AVAILABLE_DISP h
                    WHERE STATUS = 1
                    AND   DATE_CHECK  > y.COLUMN_VALUE - 1
                    AND   DATE_CHECK <= y.COLUMN_VALUE
                    AND   d.DISP = h.DISP )
AND    EXISTS     ( SELECT 'X'
                    FROM HIST_AVAILABLE_DISP h
                    WHERE STATUS = 0
                    AND   DATE_CHECK  > y.COLUMN_VALUE - 1
                    AND   DATE_CHECK <= y.COLUMN_VALUE
                    AND   d.DISP = h.DISP );
SELECT ADD_MONTHS( SYSDATE, -12 ) + LEVEL
FROM   DUAL
CONNECT BY ADD_MONTHS( SYSDATE, -12 ) + LEVEL <= SYSDATE
SELECT ADD_MONTHS( TRUNC( SYSDATE ) + 1, -12 ) + LEVEL
FROM   DUAL
CONNECT BY ADD_MONTHS( TRUNC( SYSDATE ) + 1, -12 ) + LEVEL <= TRUNC( SYSDATE ) + 1