寧電子病歷表結(jié)構(gòu)拆解:HIS對接與SQL查詢實戰(zhàn)指南)
簡介衛(wèi)寧電子病歷表結(jié)構(gòu)文檔面向醫(yī)院信息管理者、IT技術(shù)人員及醫(yī)療信息化研究人員系統(tǒng)梳理了衛(wèi)寧EMR 5.0的數(shù)據(jù)庫設(shè)計框架幫助讀者理解臨床信息系統(tǒng)的數(shù)據(jù)模型與標準化規(guī)范。資源包內(nèi)含1個doc文件約13.92MB完整收錄800余張數(shù)據(jù)表的說明、字段定義、類型、長度及值域備注。內(nèi)容覆蓋系統(tǒng)框架、財務(wù)收費、醫(yī)療信息與數(shù)據(jù)標準化等模塊如職工代碼庫、醫(yī)療項目庫、藥品分類庫、科室與病區(qū)代碼庫以及憑證類型庫、收費大項目庫、醫(yī)保分類庫、診斷代碼庫、職稱編碼庫等并涉及權(quán)限管理與數(shù)據(jù)加密等安全設(shè)計。已有1543人學習下載適合用于優(yōu)化系統(tǒng)結(jié)構(gòu)、排查數(shù)據(jù)交換問題及開展醫(yī)療大數(shù)據(jù)分析是掌握衛(wèi)寧EMR底層表結(jié)構(gòu)的重要參考。1. 衛(wèi)寧電子病歷表結(jié)構(gòu).doc一份讓 HIS 對接少走彎路的拆解思路手上拿到一份「衛(wèi)寧電子病歷表結(jié)構(gòu).doc」多數(shù)人的第一反應(yīng)是翻目錄找字段但真正做過醫(yī)院信息系統(tǒng)對接的都知道這份文檔的價值不在字段清單本身而在于它決定了你后面寫 SQL、做視圖、跑數(shù)據(jù)同步時會不會踩到坑。衛(wèi)寧健康的電子病歷產(chǎn)品線在國內(nèi)三級醫(yī)院占有率很高圍繞它的表結(jié)構(gòu)做二次開發(fā)、數(shù)據(jù)抽取、質(zhì)控分析是很多醫(yī)療 IT 從業(yè)者的日常。這篇文章不講空泛概念而是把這份表結(jié)構(gòu)文檔拆成能直接落地的路徑先搞清楚它的組織邏輯再講怎么從文檔里提取關(guān)鍵表關(guān)系最后落到查詢、同步和避坑的具體操作。適合正在做電子病歷數(shù)據(jù)對接、質(zhì)控指標開發(fā)或臨床數(shù)據(jù)倉庫建設(shè)的工程師。2. 衛(wèi)寧電子病歷表結(jié)構(gòu)的組織邏輯從文檔到數(shù)據(jù)模型2.1 先分清三類表主表、明細表、字典表拿到衛(wèi)寧電子病歷表結(jié)構(gòu)文檔不要從頭到尾逐行讀。我一般先按表名后綴和字段特征把它分成三類這個分類直接決定后面怎么寫 JOIN。第一類是主表通常以PATIENT、VISIT、EMR開頭或包含MASTER、RECORD字樣存放一次就診或一份病歷的核心標識。第二類是明細表表名里常帶DETAIL、ITEM、ENTRY一條主記錄對應(yīng)多條明細比如醫(yī)囑明細、檢驗項目明細。第三類是字典表表名多含DICT、CODE、TYPE用來做編碼翻譯比如性別代碼、科室代碼、診斷編碼。為什么先做這個分類因為衛(wèi)寧的表結(jié)構(gòu)文檔通常按模塊排列但實際查詢時你需要跨模塊 JOIN。如果不先分清主從關(guān)系很容易寫出笛卡爾積。一個典型場景查某個患者某次住院的所有檢驗結(jié)果你需要從就診主表拿到VISIT_ID再去檢驗明細表按VISIT_ID過濾最后 JOIN 字典表翻譯檢驗項目名稱。三步走缺一步結(jié)果就不完整。提示文檔里如果看到XX_ID同時出現(xiàn)在兩張表里大概率是外鍵關(guān)聯(lián)字段優(yōu)先記下來。2.2 關(guān)鍵字段的命名規(guī)律與含義衛(wèi)寧電子病歷表結(jié)構(gòu)里字段命名有比較固定的套路。掌握這些規(guī)律你甚至可以在沒有文檔的情況下猜出七八成。PATIENT_ID是患者主索引通常全院唯一但注意有些老版本用PAT_NO或MRN。VISIT_ID是就診流水號一次住院或一次門診對應(yīng)一個這是最常用的關(guān)聯(lián)鍵。VISIT_TYPE區(qū)分門診、急診、住院值通常是1、2、3或O、E、I具體看文檔里的字典說明。EMR_ID是電子病歷文檔主鍵一份病歷可能對應(yīng)多個EMR_ID比如入院記錄、病程記錄、手術(shù)記錄各一個。時間字段要特別留意。CREATE_TIME是記錄創(chuàng)建時間UPDATE_TIME是最后修改時間但衛(wèi)寧有些表用RECORD_TIME表示臨床發(fā)生時間和系統(tǒng)時間不是一回事。做質(zhì)控指標時比如「入院記錄 24 小時內(nèi)完成」你要用的是臨床時間字段不是系統(tǒng)創(chuàng)建時間。這個坑我見過不止一次查出來的數(shù)據(jù)對不上最后發(fā)現(xiàn)是時間字段選錯了。2.3 從文檔到 ER 圖手工梳理表關(guān)系的步驟文檔不會直接給你 ER 圖但你可以自己畫。步驟不復(fù)雜關(guān)鍵是耐心。第一步把文檔里所有表名抄到一張紙上或 Excel 里按模塊分組。第二步逐表標注主鍵字段通常文檔里會標PK或加粗。第三步找外鍵如果 A 表的某個字段和 B 表的主鍵同名或明顯相關(guān)畫一條線。第四步標注關(guān)系類型一對多、多對多、一對一。這個過程聽起來笨但比直接上手寫 SQL 靠譜。我一般會重點梳理三條鏈路患者-就診-病歷、就診-醫(yī)囑-醫(yī)囑明細、就診-檢驗-檢驗結(jié)果。這三條鏈路覆蓋了電子病歷數(shù)據(jù)抽取 80% 的需求。梳理完之后你會得到一張自己的 ER 圖后面寫查詢就是按圖索驥。3. 從表結(jié)構(gòu)文檔到可執(zhí)行 SQL查詢與抽取實戰(zhàn)3.1 用 VISIT_ID 串聯(lián)就診與病歷的最小查詢假設(shè)你要查某個患者最近一次住院的入院記錄內(nèi)容。文檔里告訴你就診信息在PAT_VISIT表病歷主表在EMR_DOCUMENT病歷內(nèi)容在EMR_CONTENT。下面是最小可用查詢-- 查詢指定患者最近一次住院的入院記錄 SELECT v.VISIT_ID, v.VISIT_TYPE, v.ADMISSION_TIME, d.EMR_ID, d.DOC_TYPE, -- 文檔類型入院記錄通常為 ADMISSION_NOTE c.CONTENT_TEXT -- 病歷正文可能是 CLOB 或 TEXT 類型 FROM PAT_VISIT v JOIN EMR_DOCUMENT d ON v.VISIT_ID d.VISIT_ID JOIN EMR_CONTENT c ON d.EMR_ID c.EMR_ID WHERE v.PATIENT_ID 你的患者ID AND v.VISIT_TYPE I -- I 表示住院 AND d.DOC_TYPE ADMISSION_NOTE ORDER BY v.ADMISSION_TIME DESC FETCH FIRST 1 ROW ONLY; -- 不同數(shù)據(jù)庫寫法不同Oracle 用 ROWNUM這段 SQL 的邏輯很直接先從就診表按患者和就診類型過濾拿到住院記錄再關(guān)聯(lián)病歷文檔表按文檔類型篩出入院記錄最后關(guān)聯(lián)內(nèi)容表取正文。參數(shù)方面VISIT_TYPE的值一定要查文檔里的字典表確認不同醫(yī)院實施時可能配成1或I。DOC_TYPE同理有的環(huán)境用中文編碼有的用英文縮寫。FETCH FIRST是標準 SQL 寫法Oracle 老版本要用WHERE ROWNUM 1SQL Server 用TOP 1。注意EMR_CONTENT表可能很大正文是 CLOB 字段查詢時不要SELECT *只取需要的列。3.2 醫(yī)囑明細的層級展開與過濾條件醫(yī)囑數(shù)據(jù)是電子病歷里結(jié)構(gòu)最復(fù)雜的部分之一。衛(wèi)寧的表結(jié)構(gòu)通常把醫(yī)囑拆成三層醫(yī)囑主表ORDERS、醫(yī)囑明細表ORDER_ITEMS、醫(yī)囑執(zhí)行表ORDER_EXECUTE。主表存醫(yī)囑的開立時間、開立醫(yī)生、醫(yī)囑類型明細表存具體的藥品或項目執(zhí)行表存每次執(zhí)行的時間和執(zhí)行人。查一個患者住院期間的所有長期醫(yī)囑SQL 大概長這樣-- 查詢住院期間的長期醫(yī)囑及明細 SELECT o.ORDER_ID, o.ORDER_TYPE, -- 長期/臨時文檔里查字典 o.START_TIME, o.DOCTOR_NAME, i.ITEM_NAME, i.DOSAGE, i.FREQUENCY FROM ORDERS o JOIN ORDER_ITEMS i ON o.ORDER_ID i.ORDER_ID WHERE o.VISIT_ID 目標就診號 AND o.ORDER_TYPE LONG -- 長期醫(yī)囑具體值查字典 AND o.STATUS ACTIVE -- 有效醫(yī)囑避免已停止的 ORDER BY o.START_TIME;這里的關(guān)鍵參數(shù)是ORDER_TYPE和STATUS。ORDER_TYPE在不同版本里可能是0/1、L/T或長期/臨時必須查文檔字典。STATUS字段用來過濾已停止或已作廢的醫(yī)囑如果不加這個條件你會把歷史停囑也查出來導(dǎo)致統(tǒng)計偏差。ORDER_ITEMS表里ITEM_NAME可能是編碼需要再 JOIN 藥品字典或項目字典翻譯成名稱。3.3 檢驗結(jié)果與病歷文本的關(guān)聯(lián)查詢質(zhì)控和科研場景經(jīng)常需要把檢驗結(jié)果和病歷文本關(guān)聯(lián)起來比如查某個患者血糖異常時對應(yīng)的病程記錄。衛(wèi)寧的表結(jié)構(gòu)里檢驗主表通常是LAB_TEST結(jié)果明細在LAB_RESULT病歷文本在EMR_CONTENT。關(guān)聯(lián)鍵是VISIT_ID加時間范圍。-- 查詢血糖異常前后 24 小時內(nèi)的病程記錄 SELECT l.TEST_NAME, l.RESULT_VALUE, l.REPORT_TIME, e.DOC_TYPE, e.CREATE_TIME, c.CONTENT_TEXT FROM LAB_TEST l JOIN LAB_RESULT r ON l.TEST_ID r.TEST_ID JOIN EMR_DOCUMENT e ON l.VISIT_ID e.VISIT_ID JOIN EMR_CONTENT c ON e.EMR_ID c.EMR_ID WHERE l.VISIT_ID 目標就診號 AND l.TEST_NAME LIKE %血糖% AND r.RESULT_VALUE 11.1 AND e.CREATE_TIME BETWEEN l.REPORT_TIME - INTERVAL 24 HOUR AND l.REPORT_TIME INTERVAL 24 HOUR AND e.DOC_TYPE PROGRESS_NOTE ORDER BY l.REPORT_TIME, e.CREATE_TIME;這段查詢的難點在時間范圍關(guān)聯(lián)。INTERVAL是 PostgreSQL 和 Oracle 的寫法MySQL 用DATE_SUB和DATE_ADD。另外LAB_TEST和LAB_RESULT可能是一對多一個檢驗項目多條結(jié)果JOIN 之后要注意去重。EMR_DOCUMENT和EMR_CONTENT也可能一對多如果一份病歷有多個版本需要按CREATE_TIME取最新版本。提示跨表時間關(guān)聯(lián)時先確認所有時間字段的時區(qū)和精度衛(wèi)寧有些表存的是DATE有些是TIMESTAMP混用會丟精度。4. 衛(wèi)寧電子病歷表結(jié)構(gòu)對接的避坑與排查4.1 字段值不統(tǒng)一同一含義在不同表里編碼不同現(xiàn)象寫好的查詢在 A 醫(yī)院跑得通到 B 醫(yī)院結(jié)果為空。原因衛(wèi)寧不同項目實施時字典編碼可能被本地化修改。比如性別字段有的環(huán)境存1/2有的存M/F有的存男/女。解決不要硬編碼值先查DICT或CODE類字典表或者從文檔的「值域說明」章節(jié)確認。我一般會寫一個字典查詢子查詢把編碼翻譯成統(tǒng)一值再過濾。4.2 大表查詢超時EMR_CONTENT 和 LAB_RESULT 的索引陷阱現(xiàn)象查詢病歷正文或檢驗結(jié)果時SQL 跑幾分鐘不出結(jié)果。原因EMR_CONTENT和LAB_RESULT是典型的大表幾百萬甚至上千萬行如果VISIT_ID或EMR_ID上沒有索引全表掃描必然超時。解決先確認文檔里標注的索引字段查詢時務(wù)必帶上索引列作為過濾條件。如果文檔沒標用EXPLAIN看執(zhí)行計劃必要時讓 DBA 加索引。另外CLOB 字段不要放在WHERE里做LIKE性能極差。4.3 時間字段混用CREATE_TIME 和臨床時間的區(qū)別現(xiàn)象統(tǒng)計「入院記錄 24 小時內(nèi)完成率」時數(shù)據(jù)對不上。原因用了CREATE_TIME而不是臨床記錄時間。衛(wèi)寧有些表的CREATE_TIME是系統(tǒng)寫入時間可能比實際書寫時間晚幾小時甚至幾天。解決查文檔里有沒有RECORD_TIME、WRITE_TIME、CLINICAL_TIME這類字段優(yōu)先用臨床時間。如果文檔沒寫清楚找實施人員確認或者對比幾條已知數(shù)據(jù)反推。4.4 關(guān)聯(lián)字段類型不一致隱式轉(zhuǎn)換導(dǎo)致索引失效現(xiàn)象JOIN 查詢很慢但單獨查兩張表都很快。原因關(guān)聯(lián)字段類型不一致比如 A 表VISIT_ID是VARCHAR2B 表是NUMBER數(shù)據(jù)庫做隱式轉(zhuǎn)換索引失效。解決查文檔確認字段類型寫 JOIN 時顯式轉(zhuǎn)換比如ON a.VISIT_ID TO_CHAR(b.VISIT_ID)。但更好的做法是讓 DBA 統(tǒng)一類型或者建函數(shù)索引。4.5 文檔版本與數(shù)據(jù)庫不一致字段已廢棄或新增現(xiàn)象按文檔寫的字段數(shù)據(jù)庫里報「無效標識符」。原因文檔版本落后于實際數(shù)據(jù)庫或者醫(yī)院做了定制化修改。解決先用DESC 表名或查詢USER_TAB_COLUMNS確認實際字段再對照文檔。如果發(fā)現(xiàn)文檔沒有的字段不要貿(mào)然使用先找實施確認含義。我一般會維護一份「文檔 vs 實際」的差異表每次對接新醫(yī)院先跑一遍字段比對。5. 把表結(jié)構(gòu)文檔變成可復(fù)用的數(shù)據(jù)資產(chǎn)5.1 建立自己的元數(shù)據(jù)表字段映射與血緣記錄文檔是死的數(shù)據(jù)庫是活的。我習慣在對接完一家醫(yī)院后把關(guān)鍵表的字段映射、字典值、關(guān)聯(lián)關(guān)系整理成一張元數(shù)據(jù)表存在自己的數(shù)據(jù)庫里。表結(jié)構(gòu)大概這樣CREATE TABLE MY_META_FIELD_MAP ( SOURCE_TABLE VARCHAR(100), -- 源表名 SOURCE_FIELD VARCHAR(100), -- 源字段 TARGET_TABLE VARCHAR(100), -- 目標表名 TARGET_FIELD VARCHAR(100), -- 目標字段 TRANSFORM_RULE VARCHAR(500), -- 轉(zhuǎn)換規(guī)則如字典翻譯 REMARK VARCHAR(500) -- 備注如版本差異 );這張表的好處是下次對接同版本衛(wèi)寧系統(tǒng)時直接查映射關(guān)系不用再翻文檔。TRANSFORM_RULE字段記錄字典翻譯邏輯比如SEX: 1-男, 2-女。REMARK記錄版本差異比如「V5.0 用 VISIT_IDV6.0 改用 ENCOUNTER_ID」。這個習慣幫我省了大量重復(fù)勞動。5.2 用視圖封裝復(fù)雜關(guān)聯(lián)讓業(yè)務(wù)查詢不再碰底層表底層表結(jié)構(gòu)復(fù)雜業(yè)務(wù)人員或分析師直接查容易出錯。我一般會建幾個核心視圖把常用的關(guān)聯(lián)和字典翻譯封裝進去。比如CREATE VIEW V_PATIENT_VISIT_EMR AS SELECT v.PATIENT_ID, v.VISIT_ID, v.VISIT_TYPE, v.ADMISSION_TIME, v.DISCHARGE_TIME, d.EMR_ID, d.DOC_TYPE, c.CONTENT_TEXT FROM PAT_VISIT v LEFT JOIN EMR_DOCUMENT d ON v.VISIT_ID d.VISIT_ID LEFT JOIN EMR_CONTENT c ON d.EMR_ID c.EMR_ID;視圖的好處是屏蔽底層復(fù)雜性業(yè)務(wù)查詢只需要SELECT * FROM V_PATIENT_VISIT_EMR WHERE PATIENT_ID xxx。但要注意視圖里的LEFT JOIN可能帶來性能問題如果底層表很大建議加物化視圖或定時刷新。另外視圖不要嵌套太深否則排查問題很痛苦。5.3 驗證方法用已知病例反查數(shù)據(jù)完整性做完對接后怎么驗證查出來的數(shù)據(jù)是對的我的習慣是找?guī)讉€已知病例手工核對。具體做法選一個住院患者從 HIS 系統(tǒng)里導(dǎo)出他的入院記錄、病程記錄、檢驗報告然后用自己的查詢跑一遍對比字段值和內(nèi)容。重點核對三類數(shù)據(jù)時間字段是否一致、字典翻譯是否正確、明細記錄是否漏查。如果發(fā)現(xiàn)差異先查是不是過濾條件太嚴再查是不是 JOIN 丟了記錄。我遇到過LEFT JOIN寫成INNER JOIN導(dǎo)致沒有檢驗記錄的患者被過濾掉的情況這種錯誤在統(tǒng)計總體指標時影響很大。驗證通過后把查詢固化下來作為后續(xù)開發(fā)的基準。5.4 一個具體技巧用文檔目錄反推模塊優(yōu)先級衛(wèi)寧電子病歷表結(jié)構(gòu)文檔通常有目錄目錄順序往往反映了模塊的重要性或使用頻率。我一般會先看目錄里哪些模塊被放在前面比如「患者基本信息」「就診信息」「病歷文檔」通常在前這些就是核心表優(yōu)先梳理。后面的「質(zhì)控」「科研」「接口」模塊按需處理。另外文檔里的「修訂記錄」或「版本說明」頁很關(guān)鍵它會告訴你哪些表在哪個版本新增或廢棄。如果對接的是老版本系統(tǒng)直接跳過新增表省時間。如果文檔沒有修訂記錄就對比數(shù)據(jù)庫實際表清單差異部分重點確認。提示文檔里的示例 SQL 或查詢片段不要直接抄往往和實際環(huán)境有出入只作參考。這些年做衛(wèi)寧電子病歷對接最大的教訓(xùn)就是別信文檔的「完整性」。文檔寫的是標準版醫(yī)院跑的是定制版中間差著無數(shù)實施細節(jié)。我現(xiàn)在的習慣是拿到文檔先跑一遍字段比對再找實施確認字典值最后用真實病例驗證。三步走完后面寫查詢才踏實。希望幫到你。本文還有配套的精品資源點擊獲取