3.5 有効期間サポートの演算子

Workspace Managerには、2つの期間パラメータを受け入れる関係チェック演算子と関係集合演算子が用意されており、問合せで有効期間フィルタを適用するために使用できます。

関係チェック演算子は、2つの期間に関係がある場合は整数値1を、関係がない場合は0(ゼロ)を戻します。有効期間のサポート用に次の関係チェック演算子が用意されています。

  • WM_OVERLAPSは、2つの期間がオーバーラップしているかどうかをチェックします。

  • WM_CONTAINSは、第1期間に第2期間が含まれているかどうかをチェックします。

  • WM_MEETSは、第1期間の終了時が第2期間の開始時と一致するかどうかチェックします。

  • WM_EQUALSは、2つの期間が等しい(開始時と終了時が同じ)かどうかチェックします。

  • WM_LESSTHANは、第1期間の終了時が第2期間の開始時より前かどうかチェックします。

  • WM_GREATERTHANは、第1期間の開始時が第2期間の終了時より後かどうかチェックします。

集合演算子は、2つの期間の関係を反映する期間を戻すか、2つの期間に指定の関係がない場合はNULL値を戻します。有効期間のサポート用に次の関係集合演算子が用意されています。

  • WM_INTERSECTIONは、2つの期間の交差部、すなわち両方の期間に共通する時間の範囲を戻します。

  • WM_LDIFFは、2つの期間の差異のうち左側(早い方)の部分を戻します。

  • WM_RDIFFは、2つの期間の差異のうち右側(遅い方)の部分を戻します。

関係チェック演算子は、行のwm_valid.validFrom属性とwm_valid.validTill属性のかわりに使用できます。たとえば、次の2つの問合せは等価で、どちらも1991年1月1日に有効なデータが選択されます。

SELECT * FROM employees e WHERE WM_CONTAINS (e.wm_valid,
   WMSYS.WM_PERIOD(TO_DATE('01-01-1991', 'MM-DD-YYYY'), 
                   TO_DATE('01-02-1991', 'MM-DD-YYYY')) = 1;
SELECT * from employees e 
   WHERE e.wm_valid.validFrom <= TO_DATE('01-01-1991', 'MM-DD-YYYY')
     AND e.wm_valid.validTill > TO_DATE('01-03-1991', 'MM-DD-YYYY');

これ以降は、各演算子の追加情報を説明します。各演算子は、アルファベット順に示します。

3.5.1 WM_CONTAINS

WM_CONTAINS演算子は、第1期間に第2期間が含まれているかどうかをチェックします。WM_CONTAINS(p1, p2)は、期間p1に期間p2が含まれている場合にのみ1を戻し、それ以外の場合は0 (ゼロ)を戻します。

たとえば:

WM_CONTAINS(
   WM_PERIOD(
      TO_DATE('01-01-1980', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1990', 'MM-DD-YYYY')),
   WM_PERIOD(
      TO_DATE('01-01-1985', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1988', 'MM-DD-YYYY'))) = 1
 
WM_CONTAINS(
   WM_PERIOD(
      TO_DATE('01-01-1980', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1990', 'MM-DD-YYYY')),
   WM_PERIOD(
      TO_DATE('01-01-1985', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1995', 'MM-DD-YYYY'))) = 0

例3-4では、EMPLOYEES表のうち1995年1月1日に有効だった行(つまり、WM_VALID列の値に1995年1月1日の期間が含まれている行)がすべて戻されます。

例3-4 WM_CONTAINS演算子

SELECT * FROM employees e
  WHERE WM_CONTAINS(e.wm_valid,
    wm_period(TO_DATE('01-01-1995', 'MM-DD-YYYY'),
              TO_DATE('01-02-1995', 'MM-DD-YYYY'))) = 1;

NAME                 SALARY                                                     
---------------- ----------                                                     
WM_VALID(VALIDFROM, VALIDTILL)                                                  
--------------------------------------------------------------------------------
Adams                 30000                                                     
WM_PERIOD('01-JAN-1990 12:00:00 -04:00', '01-JAN-2005 12:00:00 -04:00')

3.5.2 WM_EQUALS

WM_EQUALS演算子は、第1期間が第2期間と同じかどうかをチェックします。WM_CONTAINS(p1, p2)は、期間p1が期間p2と等しい場合にのみ1を戻し、それ以外の場合は0 (ゼロ)を戻します。

たとえば:

WM_EQUALS(
   WM_PERIOD(
      TO_DATE('01-01-1980', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1990', 'MM-DD-YYYY')),
   WM_PERIOD(
      TO_DATE('01-01-1980', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1990', 'MM-DD-YYYY'))) = 1
 
WM_EQUALS(
   WM_PERIOD(
      TO_DATE('01-01-1980', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1990', 'MM-DD-YYYY')),
   WM_PERIOD(
      TO_DATE('01-01-1985', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1995', 'MM-DD-YYYY'))) = 0

例3-5では、EMPLOYEES表のうち1990年1月1日から2005年1月1日に有効である行(つまり、WM_VALID列の値がこの期間と一致する行)がすべて戻されます。

例3-5 WM_EQUALS演算子

SELECT * FROM employees e
  WHERE WM_EQUALS(e.wm_valid,
    wm_period(TO_DATE('01-01-1990', 'MM-DD-YYYY'),
              TO_DATE('01-01-2005', 'MM-DD-YYYY'))) = 1;

NAME                 SALARY                                                     
---------------- ----------                                                     
WM_VALID(VALIDFROM, VALIDTILL)                                                  
--------------------------------------------------------------------------------
Adams                 30000                                                     
WM_PERIOD('01-JAN-1990 12:00:00 -04:00', '01-JAN-2005 12:00:00 -04:00') 

3.5.3 WM_GREATERTHAN

WM_GREATERTHAN演算子は、第1期間が第2期間より後に発生するかどうかをチェックします。WM_CONTAINS(p1, p2)は、期間p1全体が期間p2より後の場合にのみ1を戻し、それ以外の場合は0 (ゼロ)を戻します。

たとえば:

WM_GREATERTHAN(
   WM_PERIOD(
      TO_DATE('01-01-1980', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1990', 'MM-DD-YYYY')),
   WM_PERIOD(
      TO_DATE('01-01-1970', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1980', 'MM-DD-YYYY'))) = 1
 
WM_GREATERTHAN(
   WM_PERIOD(
      TO_DATE('01-01-1980', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1990', 'MM-DD-YYYY')),
   WM_PERIOD(
      TO_DATE('01-01-1970', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1981', 'MM-DD-YYYY'))) = 0

例3-6では、EMPLOYEES表のうち2001年1月1日より後にのみ有効な行(つまり、WM_VALID列のタイムスタンプがどちらも2001年1月1日より後の行)がすべて戻されます。

例3-6 WM_GREATERTHAN演算子

SELECT * FROM employees e
  WHERE WM_GREATERTHAN(e.wm_valid,
    wm_period(TO_DATE('01-01-2001', 'MM-DD-YYYY'),
              TO_DATE('01-02-2001', 'MM-DD-YYYY'))) = 1;

NAME                 SALARY                                                     
---------------- ----------                                                     
WM_VALID(VALIDFROM, VALIDTILL)                                                  
--------------------------------------------------------------------------------
Coleman               50000                                                     
WM_PERIOD('01-JAN-2003 12:00:00 -04:00', '31-DEC-9999 12:00:00 -04:00')

3.5.4 WM_INTERSECTION

WM_INTERSECTION演算子は、2つの期間の交差部、すなわち両方の指定された期間に共通する期間を戻します。WM_INTERSECTION(p1, p2)は、期間p1と期間p2の交差部の期間を戻します。

次の例では、1985年1月1日から1988年1月1日の期間が戻されます。

WM_INTERSECTION(
   WM_PERIOD(
      TO_DATE('01-01-1980', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1990', 'MM-DD-YYYY')),
   WM_PERIOD(
      TO_DATE('01-01-1985', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1988', 'MM-DD-YYYY')))

次の例では、1985年1月1日から1990年1月1日の期間が戻されます。

WM_INTERSECTION(
   WM_PERIOD(
      TO_DATE('01-01-1980', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1990', 'MM-DD-YYYY')),
   WM_PERIOD(
      TO_DATE('01-01-1985', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1995', 'MM-DD-YYYY')))

次の例では、2つの期間の交差部がないためNULL値が戻されます。

WM_INTERSECTION(
   WM_PERIOD(
      TO_DATE('01-01-1980', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1990', 'MM-DD-YYYY')),
   WM_PERIOD(
      TO_DATE('01-01-1992', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1995', 'MM-DD-YYYY')))

例3-7では、EMPLOYEES表の行ごとに、WM_PERIOD列の値が1995年1月1日の期間と交差する従業員名と期間が戻されます。

例3-7 WM_INTERSECTION演算子

SELECT e.name, WM_INTERSECTION(e.wm_valid,
  wm_period(TO_DATE('01-01-1995', 'MM-DD-YYYY'),
            TO_DATE('01-02-1995', 'MM-DD-YYYY')))
 FROM employees e;

NAME                                                                            
----------------                                                                
WM_INTERSECTION(E.WM_VALID,WM_PERIOD(TO_DATE('01-01-1995','MM-DD-
--------------------------------------------------------------------------------
Adams                                                                           
WM_PERIOD('01-JAN-1995 12:00:00 -04:00', '02-JAN-1995 12:00:00 -04:00')         
                                                                                
Baxter                                                                          
                                                                                
                                                                                
Coleman 

例3-7の出力が示すように、1995年1月1日に有効な行を持つのはAdamsのみです。

3.5.5 WM_LDIFF

WM_LDIFF演算子は、2つの期間の差異のうち左側(早い方)の部分を戻します。WM_LDIFF(p1, p2)は、期間p1と期間p1の差異のうち左側の期間を戻します。

次の例では、1980年1月1日から1985年1月1日の期間が戻されます。

WM_LDIFF(
   WM_PERIOD(
      TO_DATE('01-01-1980', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1990', 'MM-DD-YYYY')),
   WM_PERIOD(
      TO_DATE('01-01-1985', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1988', 'MM-DD-YYYY')))

次の例では、p1.validFromp2.validFromより後のため、NULL値が戻されます。

WM_LDIFF(
   WM_PERIOD(
      TO_DATE('01-01-1980', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1990', 'MM-DD-YYYY')),
   WM_PERIOD(
      TO_DATE('01-01-1975', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1995', 'MM-DD-YYYY')))

次の例では、p2p1とまったく重複しない(この場合は後である)ためNULL値が戻されます。

WM_LDIFF(
   WM_PERIOD(
      TO_DATE('01-01-1980', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1990', 'MM-DD-YYYY')),
   WM_PERIOD(
      TO_DATE('01-01-1992', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1995', 'MM-DD-YYYY')))

例3-8では、EMPLOYEES表の行ごとに、WM_PERIOD列の値が1995年1月1日の左側と異なる従業員名と期間が戻されます。

例3-8 WM_LDIFF演算子

SELECT e.name, WM_LDIFF(e.wm_valid,
  wm_period(TO_DATE('01-01-1995', 'MM-DD-YYYY'),
            TO_DATE('01-02-1995', 'MM-DD-YYYY')))
 FROM employees e;

NAME                                                                            
----------------                                                                
WM_LDIFF(E.WM_VALID,WM_PERIOD(TO_DATE('01-01-1995','MM-DD-YYYY'),
--------------------------------------------------------------------------------
Adams                                                                           
WM_PERIOD('01-JAN-1990 12:00:00 -04:00', '01-JAN-1995 12:00:00 -04:00')         
                                                                                
Baxter                                                                          
                                                                                
                                                                                
Coleman

例3-8の出力が示すように、左側の差異期間中に有効な行を持つのはAdamsのみです。

3.5.6 WM_LESSTHAN

WM_LESSTHAN演算子は、第1期間が第2期間より前に発生するかどうかをチェックします。WM_CONTAINS(p1, p2)は、期間p1全体が期間p2より前の場合にのみ1を戻し、それ以外の場合は0 (ゼロ)を戻します。

たとえば:

WM_LESSTHAN(
   WM_PERIOD(
      TO_DATE('01-01-1980', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1990', 'MM-DD-YYYY')),
   WM_PERIOD(
      TO_DATE('01-01-1991', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1992', 'MM-DD-YYYY'))) = 1
 
WM_LESSTHAN(
   WM_PERIOD(
      TO_DATE('01-01-1980', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1990', 'MM-DD-YYYY')),
   WM_PERIOD(
      TO_DATE('01-01-1989', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1992', 'MM-DD-YYYY'))) = 0

例3-9では、EMPLOYEES表のうち2010年1月1日より前にのみ有効な行(つまり、WM_VALID列のタイムスタンプがどちらも2001年1月1日より前の行)がすべて戻されます。

例3-9 WM_LESSTHAN演算子

SELECT * FROM employees e
  WHERE WM_LESSTHAN(e.wm_valid,
    wm_period(TO_DATE('01-01-2010', 'MM-DD-YYYY'),
              TO_DATE('01-02-2010', 'MM-DD-YYYY'))) = 1;

NAME                 SALARY                                                     
---------------- ----------                                                     
WM_VALID(VALIDFROM, VALIDTILL)                                                  
--------------------------------------------------------------------------------
Adams                 30000                                                     
WM_PERIOD('01-JAN-1990 12:00:00 -04:00', '01-JAN-2005 12:00:00 -04:00')

3.5.7 WM_MEETS

WM_MEETS演算子は、第1期間の終了時が第2期間の開始時かどうかをチェックします。WM_MEETS(p1, p2)は、p1.validTill = p2.validFromの場合にのみ1を、それ以外の場合は0(ゼロ)を戻します。

たとえば:

WM_MEETS(
   WM_PERIOD(
      TO_DATE('01-01-1980', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1990', 'MM-DD-YYYY')),
   WM_PERIOD(
      TO_DATE('01-01-1990', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1995', 'MM-DD-YYYY'))) = 1
 
WM_MEETS(
   WM_PERIOD(
      TO_DATE('01-01-1980', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1990', 'MM-DD-YYYY')),
   WM_PERIOD(
      TO_DATE('01-01-1992', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1995', 'MM-DD-YYYY'))) = 0

例3-10では、EMPLOYEES表のうち、有効日付期間の終了タイムスタンプが2005年1月1日から2006年1月1日の期間開始日と同じである場合(つまり、WM_VALID.validTillが指定期間の開始日と等しい場合)にのみ有効な行がすべて戻されます。

例3-10 WM_MEETS演算子

SELECT * FROM employees e
  WHERE WM_MEETS(e.wm_valid,
    wm_period(TO_DATE('01-01-2005', 'MM-DD-YYYY'),
              TO_DATE('01-01-2006', 'MM-DD-YYYY'))) = 1;

NAME                 SALARY                                                     
---------------- ----------                                                     
WM_VALID(VALIDFROM, VALIDTILL)                                                  
--------------------------------------------------------------------------------
Adams                 30000                                                     
WM_PERIOD('01-JAN-1990 12:00:00 -04:00', '01-JAN-2005 12:00:00 -04:00')

3.5.8 WM_OVERLAPS

WM_OVERLAPS演算子は、2つの期間がオーバーラップしているかどうかをチェックします。WM_OVERLAPS(p1, p2)は、期間p1と期間p2がオーバーラップしている場合は1を戻し、それ以外の場合は0 (ゼロ)を戻します。

たとえば:

WM_OVERLAPS(
   WM_PERIOD(
      TO_DATE('01-01-1980', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1990', 'MM-DD-YYYY')),
   WM_PERIOD(
      TO_DATE('01-01-1985', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1995', 'MM-DD-YYYY'))) = 1
 
WM_OVERLAPS(
   WM_PERIOD(
      TO_DATE('01-01-1980', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1990', 'MM-DD-YYYY')),
   WM_PERIOD(
      TO_DATE('01-01-1970', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1980', 'MM-DD-YYYY'))) = 0

例3-11では、EMPLOYEES表のうち、有効日付の範囲が1990年1月1日から2000年1月1日の期間とオーバーラップしている行がすべて戻されます。

例3-11 WM_OVERLAPS演算子

SELECT * FROM employees e
  WHERE WM_OVERLAPS(e.wm_valid,
    wm_period(TO_DATE('01-01-1990', 'MM-DD-YYYY'),
              TO_DATE('01-01-2000', 'MM-DD-YYYY'))) = 1;

NAME                 SALARY                                                     
---------------- ----------                                                     
WM_VALID(VALIDFROM, VALIDTILL)                                                  
--------------------------------------------------------------------------------
Adams                 30000                                                     
WM_PERIOD('01-JAN-1990 12:00:00 -04:00', '01-JAN-2005 12:00:00 -04:00') 

3.5.9 WM_RDIFF

WM_RDIFF演算子は、2つの期間の差異のうち右側(遅い方)の部分を戻します。WM_RDIFF(p1, p2)は、期間p1と期間p2の差異のうち右側の期間を戻します。

次の例では、1988年1月1日から1990年1月1日の期間が戻されます。

WM_RDIFF(
   WM_PERIOD(
      TO_DATE('01-01-1980', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1990', 'MM-DD-YYYY')),
   WM_PERIOD(
      TO_DATE('01-01-1985', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1988', 'MM-DD-YYYY')))

次の例では、p1.validTillp2.validTillより前のため、NULL値が戻されます。

WM_RDIFF(
   WM_PERIOD(
      TO_DATE('01-01-1980', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1990', 'MM-DD-YYYY')),
   WM_PERIOD(
      TO_DATE('01-01-1975', 'MM-DD-YYYY'), 
      TO_DATE('01-01-1995', 'MM-DD-YYYY')))

例3-12では、EMPLOYEES表の行ごとに、WM_PERIOD列の値が1995年1月1日より後の異なる従業員名と期間が戻されます。

例3-12 WM_RDIFF演算子

SELECT e.name, WM_RDIFF(e.wm_valid,
  wm_period(TO_DATE('01-01-1995', 'MM-DD-YYYY'),
            TO_DATE('01-02-1995', 'MM-DD-YYYY')))
 FROM employees e;

NAME                                                                            
----------------                                                                
WM_RDIFF(E.WM_VALID,WM_PERIOD(TO_DATE('01-01-1995','MM-DD-YYYY'),
--------------------------------------------------------------------------------
Adams                                                                           
WM_PERIOD('02-JAN-1995 12:00:00 -04:00', '01-JAN-2005 12:00:00 -04:00')         
                                                                                
Baxter                                                                          
                                                                                
                                                                                
Coleman                                                                         
WM_PERIOD('01-JAN-2003 12:00:00 -04:00', '31-DEC-9999 12:00:00 -04:00') 

例3-12の出力が示すように、右側の差異期間中に有効な行を持つのはAdamsとColemanのみです。