Optimization

在單行中搜尋成對的日期/時間值

  • November 27, 2012

我有一個舊版 IBM DB2 數據庫表,其中包含大量電話記錄。它有 ID、客戶編號、接聽電話的員工等列。每個電話的日期/時間保存在一對列中,ROSDAT 和 ROSTIM。ROSDAT 是一個 8 字節的數字列,而 ROSTIM 是一個 6 字節的數字。例子:

ROSDAT    ROSTIM  
20111006  163243  
20111007  012335

所以第一行的日期是 2011-10-06,時間是 16:32:43。該表中有數百萬條記錄,我正在嘗試進行查詢,按時間和日期進行搜尋。到目前為止,我發現這樣做的唯一方法是將時間/日期列連接成一個大數字,如下所示:

`select * from PHONELOGTABLE

where ROSDAT * power(10, 6) + ROSTIM >= 20111015124500

and ROSDAT * power(10, 6) + ROSTIM <= 20111116013000`

這將搜尋從 2011-10-15 12:45:00 到 2012-11-16 01:30:00 的所有內容。它可以工作,但連接意味著(據我所知)ROSDAT 和 ROSTIM 列上的索引不能使用,因此查詢比它應該的要慢。在我看來,應該有一種方法可以通過加入或其他方式來做到這一點。

我試過這個,但無法讓它工作,我知道我錯過了一些東西:

`select a.* from PHONELOGTABLE a join PHONELOGTABLE b on a.ID = b.ID where a.ROSDAT >= 20111015 and b.ROSTIM >= 124500

and a.ROSDAT <= 20111116 and b.ROSTIM <= 013000`

有人有想法嗎?

我不確定 db2 語法,但是這個怎麼樣?

-- declare your 4 variables
@START_ROSDAT
@STOP_ROSDAT
@START_ROSTIM
@STOP_ROSTIM

select  *
from    PHONELOGTABLE
where   (   @start_rosdat &lt;&gt; @stop_rosdat                                    -- search covers more than 1 day
          and  (       (ROSDAT &gt; @START_ROSDAT AND ROSDAT &lt; @STOP_ROSDAT)   -- catches all full days between start and stop
                  or   (ROSDAT = @START_ROSDAT AND ROSTIM &gt;= @START_ROSTIM) -- catches everything on the "start" day
                  or   (ROSDAT = @STOP_ROSDAT AND ROSTIM &lt;= @STOP_ROSTIM)   -- catches everything on the "stop" day
               )
       )
 or    (   @start_rosdat = @stop_rosdat                                     -- only search a single "day"
          and  (       (ROSDAT = @START_ROSDAT AND ROSTIM &gt;= @START_ROSTIM)
                  and  (ROSDAT = @STOP_ROSDAT AND ROSTIM &lt;= @STOP_ROSTIM)
               )
       )

WHERE條件簡化了一點(括號只是為了清楚起見,您可以安全地刪除它們):

where   ( ROSDAT &gt; @start_rosdat   and  ROSDAT &lt; @stop_rosdat )

  or   (  @start_rosdat &lt; @stop_rosdat 
     and  ROSDAT = @start_rosdat  and  ROSTIM &gt;= @start_rostim )

  or   (  @start_rosdat &lt; @stop_rosdat 
     and  ROSDAT = @stop_rosdat   and  ROSTIM &lt;= @stop_rostim  )

  or   (  @start_rosdat = @stop_rosdat 
     and  ROSDAT = @start_rosdat  and  ROSTIM &gt;= @start_rostim
                                  and  ROSTIM &lt;= @stop_rostim  )

和另一個版本(此處需要括號):

where   (  ROSDAT &gt; @start_rosdat  
      or  ROSDAT = @start_rosdat  and  ROSTIM &gt;= @start_rostim )

  and  (  ROSDAT &lt; @stop_rosdat
      or  ROSDAT = @stop_rosdat   and  ROSTIM &lt;= @stop_rostim  )

引用自:https://dba.stackexchange.com/questions/29010