SQLによるDPCデータ分析―MEDI ARROWSとともに

藤森研司『DPCデータ分析―アクセス・SQL活用編』

山形県の寄附講座事業の一環として、県内病院のDPCデータ(個人情報を外した診療録情報、診療明細情報、行為明細情報)を集積し、診療実態・治療実績等の分析を進めている。

ニッセイ情報テクノロジー社のMEDI ARROWSを採用して分析をしてきたのだが、このソフトウェアのありがたいところは、構築されたデータベースがユーザーに開放されており、ODBCやSQLで利用できることだ。DPC分析ソフトは数々あるが、いずれも分析できる内容・容量に限界がある。したがって、データベースにユーザーが直接アクセスできることは必須である。

では、データベースにどのようにアクセスすべきなのか。当初はAccessを用いていたが、そもそもデータベース操作の経験など私にはない。しかも、Accessは、ファイルサイズに上限があり、処理スピードも遅く、クエリの全体像の把握も容易ではない。したがって、試行錯誤もしづらい。とはいえ、直にSQL文を書く知識などろくになかった……。

しかし、『DPCデータ分析―アクセス・SQL活用編』などの著者でもある藤森研司先生にお会いする機会があり、その際にSQLのすばらしさの一端を教わった。山形市立病院済生館の岩渕先生(呼吸器内科)がスラスラとクエリを書いてしまうのも目の当たりにした。一念発起せざるをえない。SQL Serverで取り組むことになった(さらに岩淵先生にはデータベースをインタラクティブかつフレキシブルに集計・可視化するツールとしてQlikViewを紹介いただいた←これは本当に便利! 独学で十分に使いこなせる)。

SQL習得の道

ミック著『SQL ゼロからはじめるデータベース操作』ミック著『達人に学ぶ SQL徹底指南書』

『DPCデータ分析―アクセス・SQL活用編』では、ミック著『達人に学ぶ SQL徹底指南書』が良書として推薦されているが、これは「ある程度SQL文が書けるようになると、読んでためになる良書」であるという。そこで、同著『SQL―ゼロからはじめるデータベース操作』を手に取ったところ、とてもわかりやすい。プログラミングそのものの知識がなくとも、ほとんどひっかかることなく「おもしろく」読み切ることができた。

とはいえ、実を言うと、相関サブクエリとEXISTS述語の節+練習問題は流し読みしていた……「分かった気になっていただけ」である。『達人に学ぶSQL徹底指南書』が自分の浅はかさに気づかせてくれた。「1-2 自己結合の使い方」でさっそく躓いた。「同じテーブルに異なるテーブル名が与えられて、それぞれを参照している??」と頭が混乱したが、『ゼロからはじめるデータベース操作』を読み直すと、相関サブクエリの節にしっかりと書いてあった……。

確かにこのイメージをつかむことで、「集合指向言語としてのSQL」の本領世界がだんだんと開かれていく。『指南書』によれば、SQLの基礎には、集合論と述語論理があるという。私は、しっかりと、その2つを体現していた相関サブクエリとEXISTS述語の節を流し読みしていたのだ! いずれにせよ、こうして、2,000円前後でSQLの基礎が確実に「楽しく」学べるのだから、本書は安い(世の中には、もっと高くて、不親切で、そして何も残らない本があふれている!)。

SQLによるDPCデータ分析の一例

ただし、実際のDPCデータ分析で複雑なクエリを必要とする機会はそれほどない。たとえば、医療の質評価事業の「術後の大腿骨頸部骨折/転子部骨折の発生率」を算出する場合、手術1~5から「K920$ 輸血」などを除外した上で、手術1~5の各手術日の最古日を手術日として術後日数を算出しなければならないが、初学者であった私にはその方法が良く分からなかった。そこで、ニッセイ情報テクノロジー社のKさんよりご教示いただいて、下記のようなクエリを作成することになった。

SELECT
temp1.[000 入院番号],
min(temp1.計算用手術日),
temp1.[014 退院年月日],
datediff(d, convert(datetime, min(temp1.計算用手術日)), convert(datetime, temp1.[014 退院年月日]))
FROM (
select
[04_カルテ情報].*,
case when [057 手術1の点数表コード] in (‘K907’, ‘K908’, ‘K914’, ‘K915’)
or [057 手術1の点数表コード] like ‘K913%’
or [057 手術1の点数表コード] like ‘K920%’
then NULL else [060 手術1・手術日] end as 計算用手術日
from [04_カルテ情報]

union all select
[04_カルテ情報].*,
case when [064 手術2の点数表コード] in (‘K907’, ‘K908’, ‘K914’, ‘K915’)
or [064 手術2の点数表コード] like ‘K913%’
or [064 手術2の点数表コード] like ‘K920%’
then NULL else [067 手術2・手術日] end as 計算用手術日
from [04_カルテ情報]

union all select
[04_カルテ情報].*,
case when [071 手術3の点数表コード] in (‘K907’, ‘K908’, ‘K914’, ‘K915’)
or [071 手術3の点数表コード] like ‘K913%’
or [071 手術3の点数表コード] like ‘K920%’
then NULL else [074 手術3・手術日] end as 計算用手術日
from [04_カルテ情報]

union all select
[04_カルテ情報].*,
case when [078 手術4の点数表コード] in (‘K907’, ‘K908’, ‘K914’, ‘K915’)
or [078 手術4の点数表コード] like ‘K913%’
or [078 手術4の点数表コード] like ‘K920%’
then NULL else [081 手術4・手術日] end as 計算用手術日
from [04_カルテ情報]

union all select
[04_カルテ情報].*,
case when [085 手術5の点数表コード] in (‘K907’, ‘K908’, ‘K914’, ‘K915’)
or [085 手術5の点数表コード] like ‘K913%’
or [085 手術5の点数表コード] like ‘K920%’
then NULL else [088 手術5・手術日] end as 計算用手術日
from [04_カルテ情報]
) as temp1
GROUP BY temp1.[000 入院番号], temp1.[014 退院年月日]
ORDER BY temp1.[000 入院番号];

実際には、さらに除外対象となる病名を外すために約160行の選択条件句(WHERE句)が要り、施設コード(13施設)、年度(4年度分)による分類が入っているのだが、それでも、研究室のサーバーでは10分程度で処理できてしまう。また、パス分析など各診療行為の関係を見る場合でも、行為明細を自己結合すれば簡単にできる。したがって、DPCデータ分析の際に、上述の『指南書』を超える複雑なクエリが必要であると感じたことはない(いまのところ?)。

それにしても、『指南書』などを読んだり、上述のKさんにご教示いただいたりするたびに、まさにパズルの解法を聞くように「なるほど!」と思わせてくれて、おもしろい。しかも、『指南書』でも中級編だというのだから、データベースの世界はとても奥が深いのだ。

この本〔高野豊『rootから/へのメッセージ』〕に出会って以来、私は、データベースに対して謙虚な姿勢で臨むことを心がけるようになりました。もし自分がこの世界に退屈さを感じているとすれば、それは世界の責任ではなく、きっと自分がまだ世界の豊かさを発見することができていないからだ。この世界はきっと、私の知らない豊かな可能性を蔵しているはずだ、と。そのように態度を改めることによって初めて、私はデータベースの世界の深部へ向かって、少しずつ降りていくことができるようになったのです。(『指南書』p.315)

書籍情報

明日の医療に活かすDPCデータの分析手法と活用
藤森研司、松田晋哉
じほう
売り上げランキング: 126,908
達人に学ぶ SQL徹底指南書 (CodeZine BOOKS)
ミック
翔泳社
売り上げランキング: 19,882

この記事のタグ