飲み合わせ・食べ合わせの検索の例

 複数の薬について危険な飲み合わせを含んでいないか、複数の食品について特定の食べ合わせを含んでいないか、というチェックを行う場合の設定です。具体的に言いますと、複数のレコードで表されている値の組み合わせが、別に定められた組み合わせを含んでいるかどうかを検索するというものです。

f:id:accs2014:20180531231828p:plain:right:w500

 実例として、薬の飲み合わせについてのデータベースの例をみてみます。テーブルの例(一部テーブルのリレーションシップ画面)はこのようになります。
 「T処方」と「T処方明細」は1回の処方ごとに処方された薬の内容を記録しており、「T飲合」と「T飲合明細」は危険な飲み合わせとなる薬の組み合わせ定義を記録しています。


f:id:accs2014:20180601001529p:plain:right:w600

 検索に最低限必要となる2つのテーブル(T処方明細、T飲合明細)の例はこのようなものです。
 T処方明細を見ますと、処方IDが2の処方において4種の薬が処方されおり、それぞれの薬IDは2,3,5,7となっています。
 一方のT飲合明細を見ますと、飲合IDが3の飲み合わせとして、薬IDが2,7の組み合わせが定義されています。
 よって、この処方は危険な飲み合わせを含んでいる({2,3,5,7}⊇{2,7})と判断されます。
 処方によっては複数の飲み合わせに抵触する場合も考えられますが、そのような処方IDと飲合IDの組み合わせをすべて列挙するものとします。

 なお、3種以上の薬からなる飲み合わせ(例:飲合ID=4)は、そのすべてを含む場合に飲み合わせに抵触するものとみなします。


f:id:accs2014:20180531231822p:plain:right:w500

 前置きが長くなりましたので一気にSQLです;-o-)



SELECT DISTINCT T処方明細.処方ID, T飲合明細.飲合ID
FROM T処方明細, T飲合明細
WHERE T飲合明細.飲合ID Not In
(SELECT 飲合ID FROM T飲合明細 WHERE 薬CD Not In
(SELECT 薬CD FROM T処方明細 AS T処方明細_1 WHERE T処方明細_1.処方ID = T処方明細.処方ID));

 2つのテーブルのすべての行の組み合わせに対し、各行ごとに処方に含まれない薬を含む飲合IDをピックアップ。それら以外の飲合IDが「抵触する飲合ID」となります。「抵触する飲合ID」がなければ抽出から除き、残った行をDISTINCTしてまとめています。やり方的にかなり遅いかとは思います;-o-)


f:id:accs2014:20180601001526p:plain:right:w300

 データシートビューです。
 処方IDが4である処方は2種の飲み合わせに抵触していますが、そのことも確認できます。


 結びになりますが、現実問題として3種以上の薬の組み合わせによる飲み合わせというのは一般的ではないものと思われます。2種の薬の組み合わせで足りるなら飲み合わせの定義も横持ちにした方が簡単ですし、検索のやり方もだいぶ違ってくると思われます。
 それと、上記例の場合でも薬CDを横持ち化するユーザー定義関数を作って比較する方が楽な気がしてきました;-o-)