トップページに戻る    次のSQLパズルへ    前のSQLパズルへ

10-142 命題成立時のブール代数の同値変形

SQLパズル

:i_str_date   <= :i_end_date
と
MASTER_S_DATE <= MASTER_E_DATE
が成立しているとして、

以下の条件式を、同値変形によって、簡略化させる

    MASTER_S_DATE >= :i_str_date
AND MASTER_S_DATE <= :i_end_date
 OR MASTER_E_DATE >= :i_str_date
AND MASTER_E_DATE <= :i_end_date
 OR MASTER_S_DATE <= :i_str_date
AND MASTER_E_DATE >= :i_end_date

こちらを参考にさせていただきました


SQL

    MASTER_S_DATE <= :i_end_date
AND MASTER_E_DATE >= :i_str_date


解説

MASTER_S_DATE >= :i_str_date をA
MASTER_S_DATE <= :i_end_date をB
MASTER_E_DATE >= :i_str_date をC
MASTER_E_DATE <= :i_end_date をD
MASTER_S_DATE <= :i_str_date をE
MASTER_E_DATE >= :i_end_date をF
とおくと

    MASTER_S_DATE >= :i_str_date
AND MASTER_S_DATE <= :i_end_date
 OR MASTER_E_DATE >= :i_str_date
AND MASTER_E_DATE <= :i_end_date
 OR MASTER_S_DATE <= :i_str_date
AND MASTER_E_DATE >= :i_end_date

はこう置けます。
A*B + C*D + E*F

:i_str_date <= :i_end_date と
MASTER_S_DATE <= MASTER_E_DATE より
以下の命題が成立

 1  A⇒C
 2  D⇒B
 3  E⇒B
 4  F⇒C
 5  Aが偽⇒E
 6  Bが偽⇒F
 7  Cが偽⇒D
 8  Dが偽⇒F
 9  Eが偽⇒A
10  Fが偽⇒D

A*B + C*D + E*F
= A*C*B + C*D*B + E*B*F*C
= B*C*(A + D + E*F)

E*Fが偽ならば、命題9と命題10より
AとDの、少なくとも1つが真
よって
A + D + E*F=1
よって
B*C*(A + D + E*F) = B*C

すなわち
    MASTER_S_DATE >= :i_str_date
AND MASTER_S_DATE <= :i_end_date
 OR MASTER_E_DATE >= :i_str_date
AND MASTER_E_DATE <= :i_end_date
 OR MASTER_S_DATE <= :i_str_date
AND MASTER_E_DATE >= :i_end_date

と
    MASTER_S_DATE <= :i_end_date
AND MASTER_E_DATE >= :i_str_date
は同値である。

この場合は、
対象が終了する前に開始して
対象が開始してから終了した
と考えてもいいですけどね。
「プログラマのためのSQL 第2版」の172ページに書いてあった考え方です。

■■■■■■■■■■■■■■■■■■■■■■■■■■■■
1  A⇒C
2  D⇒B
3  E⇒B
4  F⇒C

A*B + C*D + E*F
= A*C*B + C*D*B + E*B*F*C

この変形は、

条件Xが真ならば条件Yも真である場合は、
条件Xが真、かつ、条件Yが真
であることは、
条件Xが真であることと同値である。

X=3ならばY=1である場合は、
X=3、かつ、Y=1
であることは、
X=3であることと同値である。

なんてのを使ってます。

同値の証明は
X⇒YかつY⇒X
が成立すれば
X⇔Y
を使うと分かりやすいと思います。

■■■■■■■■■■■■■■■■■■■■■■■■■■■■
A*B + C*D + E*F
= A*C*B + C*D*B + E*B*F*C
は、backward stepの考え方を使ってます。

中学数学や高校数学で、
因数分解を使って、問題を解きやすくする感覚に近いですね。

同値変形の資料