DPCデータの分析とかやるブログ

DPCデータの分析なんかをテキトーにやってます。

行値式を使った条件指定について(Postgres SQL前提)

保険算定というのは奇々怪々です。
あまりにも制度が複雑になりすぎて、「○○を行った患者さんで、××は算定してなくて、でも△△を算定してる人が知りたい」みたいな問題が割と出てきます。
一つ一つの条件は単純ですが、重なってくると面倒ですね。
さて、入院データを元に抽出をかけるとすると、「一人」ではなく「一入院」を単位とするのが一般的です。
つまり、先ほどのめんどくさいパターンマッチは、「その人」ではなく「その入院」に対してかけないといけません。
具体的に言えば、データ識別番号だけでは駄目で、入院年月日も使って探す必要があります。
(DPCデータの分析では、まずデータ識別番号と入院年月日を組み合わせてキーを作るのが基本です) では実際にやってみましょう。こんな感じでしょうか。

select *
from ef1612
Where 診療明細名称 LIKE '%探しているもの%'
AND (データ識別番号,入院年月日) NOT IN (select distinct データ識別番号,入院年月日
from efile
Where 診療明細名称 LIKE '%算定してない条件%')
AND (データ識別番号,入院年月日) IN (select distinct データ識別番号,入院年月日
from efile 
Where 診療明細名称 LIKE '%算定してる条件%')

--以下延々と続く

さて、上記のSQLは一体何をしているのでしょう。

AND (データ識別番号,入院年月日) IN (select distinct データ識別番号,入院年月日
from efile
Where 診療明細名称 LIKE '%なんとか%')

SQLでは、INを使って一定の条件に当てはまるデータを抽出出来ます。イメージとしては

123 in [123,456,789]

のような処理を考えてみましょう。上の例では123は右側のリストの先頭にあります。 同じように上記の例では、データ識別番号,入院年月日ペアが存在するかどうかを探しているのです。
INの横で唐突にSELECT文が走っていますが、よく見ると'データ識別番号,入院年月日'のペアを引っ張るようになっています。
逆に特定条件を満たしていないものを探したければ、NOT INを使えばいいだけです。 この例で分かるとおり、ブロックを並び続けることで、いくらでも条件を追加出来ます。 ただし、上記の()を使ってペア(もしくはそれ以上の複数条件)を使う記法は行値式といって、Postgresなど一部SQLにしか実装されていません。 (代表的なところでは、MicrosoftSQL Serverでは未対応です)
その場合はEXISTSなどを使って書き換える必要があります。 非常に便利で、自分は実務で連発してますが、案外使わないもんなんでしょうか・・・?