Mine

รูปภาพของฉัน
หาดใหญ่, ภาคใต้, Thailand
ชอบเอาใจ แต่ก็เอาแต่ใจ

วันศุกร์ที่ 5 พฤศจิกายน พ.ศ. 2553

จำนวนผู้ป่วยเบาหวาน(DM)และความดัน(HT)ของสิทธิUC

สวัสดีค่ะ วันก่อนได้มีโอกาสเขียน SQL ตัวนึงค่ะ ก็เลยอยากเอามาฝากกันทุกคน
รายละเอียด คือ จำนวนผู้ป่วยนอกเบาหวานที่มีความดันร่วมด้วย โดยมีความดัน <= 130/80 เฉพาะสิทธิ UC เท่านั้น ในช่วงปีงบประมาณ 2553
มาตีความของรายละเอียดที่ต้องการก่อนดีกว่าค่ะ ว่าเขาต้องการอะไรกันแน่
1. ผู้ป่วยนอกเบาหวานที่มีความดันร่วมด้วย หมายถึง ผู้ที่มารับบริการที่ไม่มีการ Admit ด้วยโรคเบาหวาน และมีโรคความดัน จากการวินิจฉัยของแพทย์ และผู้ให้รหัส ซึ่งเราสามารถตรวจสอบจากการให้รหัส ICD-10 ได้ นั่นคือ ผู้รับบริการจะได้รับ ICD-10 ในช่วง E10-E14 (เบาหวาน) และ I10-I15 (ความดัน)
2. ความดัน <= 130/80 หมายถึง ผู้ที่มารับบริการได้วัดความดัน และความดันช่วงบนมีค่าน้อยกว่าหรือเท่ากับ 130 และ ความดันช่วงล่างต้องมีค่าน้องกว่าหรือเท่ากับ 80
3. สิทธิ UC หมายถึง ผู้มารับบริการที่ใช้สิทธิของหลักประกันสุขภาพ โดยสามารถตรวจสอบได้จาก maininscl = "WEL", "UCS", ""
4. ปีงบประมาณ 2553 หมายถึง ผู้มารับบริการในช่วงวันที่ 01 ตุลาคม 2552 ถึง 30 กันยายน 2553
สรุปตารางที่เราต้องใช้ มีดังนี้
- t_visit บอกถึงข้อมูลรับบริการในแต่ละครั้ง
- t_diag_icd10 บอกถึง รหัสที่ได้รับวินิจฉัยในการรับบริการแต่ละครั้ง
- t_visit_vital_sign บอกถึงค่าความดันที่วัดในการรับบริการ
- t_visit_payment บอกถึงสิทธิที่ผู้รับบริการใช้ในการมารับบริการแต่ละครั้ง
- b_contract_plans บอกถึงสิทธิของโรงพยาบาลว่ามีสิทธิอะไรบ้าง และเชื่อมโยงไปยังสิทธิของหลักประกันสุขภาพในสิทธิอะไร
- r_rp1853_instype บอกถึงสิทธิของหลักประกันสุขภาพ
งั้นเรามาเริ่มเขียน Query กันทีละขั้นเลยนะคะ เพื่อให้ได้ผลตามที่เราต้องการ
1. บอกว่าได้รับการวินิจฉัยเบาหานหรือความดัน
select t_visit.t_visit_id, t_visit.visit_vn, substring(t_visit.visit_begin_visit_time,1,10) ,t_diag_icd10.diag_icd10_number
from t_visit inner join t_diag_icd10
    on t_visit.t_visit_id = t_diag_icd10.diag_icd10_vn
where t_diag_icd10.diag_icd10_active = '1' --รายการ ICD-10 ไม่ถูกยกเลิก
and t_visit.f_visit_type_id = '0' --เฉพาะผู้ป่วยนอก
and t_visit.f_visit_status_id <> '4' --รายการ visit ไม่ถูกยกเลิก
and (upper(substring(t_diag_icd10.diag_icd10_number,1,3)) between 'E10' and 'E14' --เบาหวาน
        or
        upper(substring(t_diag_icd10.diag_icd10_number,1,3)) between 'I10' and 'I15') --ความดัน
and substring(t_visit.visit_begin_visit_time,1,10) between '2552-10-01' and '2553-09-30';
2. แต่เราต้องการการวินิจฉัยเบาหวาน และความดัน จากข้อ 1 คงบอกไม่ได้เพราะอยู่คนละบรรทัด อีกทางที่เราจะทำได้ คือ มองตาราง t_diag_icd10 เป็น 2 ตารางก็ได้ ดังนี้
select t_visit.t_visit_id, t_visit.visit_vn, substring(t_visit.visit_begin_visit_time,1,10) ,icd_dm.diag_icd10_number,icd_ht.diag_icd10_number
from t_visit inner join t_diag_icd10 as icd_dm --แทนตารางเบาหวาน
    on (t_visit.t_visit_id = icd_dm.diag_icd10_vn
    and icd_dm.diag_icd10_active = '1' --รายการ ICD-10 ไม่ถูกยกเลิก
    and upper(substring(icd_dm.diag_icd10_number,1,3)) between 'E10' and 'E14' ) --เบาหวาน
 inner join t_diag_icd10 as icd_ht --แทนตารางความดัน
    on (t_visit.t_visit_id = icd_ht.diag_icd10_vn
    and icd_ht.diag_icd10_active = '1' --รายการ ICD-10 ไม่ถูกยกเลิก
    and upper(substring(icd_ht.diag_icd10_number,1,3)) between 'I10' and 'I15') --ความดัน
where t_visit.f_visit_type_id = '0' --เฉพาะผู้ป่วยนอก
and t_visit.f_visit_status_id <> '4' --รายการ visit ไม่ถูกยกเลิก
and substring(t_visit.visit_begin_visit_time,1,10) between '2552-10-01' and '2553-09-30';
3. เมื่อเราได้ผู้ป่วยเบาหวานและมีความดันร่วมด้วยแล้ว เราก็มา Focus ที่สิทธิที่รับบริการเพิ่มเติม ดังนี้

select t_visit.t_visit_id, t_visit.visit_vn, substring(t_visit.visit_begin_visit_time,1,10) ,icd_dm.diag_icd10_number,icd_ht.diag_icd10_number,r_rp1853_instype.maininscl
from t_visit inner join t_diag_icd10 as icd_dm --แทนตารางเบาหวาน
    on (t_visit.t_visit_id = icd_dm.diag_icd10_vn
    and icd_dm.diag_icd10_active = '1' --รายการ ICD-10 ไม่ถูกยกเลิก
    and upper(substring(icd_dm.diag_icd10_number,1,3)) between 'E10' and 'E14' ) --เบาหวาน
 inner join t_diag_icd10 as icd_ht --แทนตารางความดัน
    on (t_visit.t_visit_id = icd_ht.diag_icd10_vn
    and icd_ht.diag_icd10_active = '1' --รายการ ICD-10 ไม่ถูกยกเลิก
    and upper(substring(icd_ht.diag_icd10_number,1,3)) between 'I10' and 'I15') --ความดัน
inner join t_visit_payment --สิทธิที่ผู้รับบริการใช้ในการรับบริการ
   
on t_visit.t_visit_id = t_visit_payment.t_visit_id
   
and t_visit_payment.visit_payment_active = '1' --จะต้องไม่ถูกยกเลิก
inner join b_contract_plans
   
on t_visit_payment.b_contract_plans_id = b_contract_plans.b_contract_plans_id
inner join r_rp1853_instype
  
  on b_contract_plans.r_rp1853_instype_id = r_rp1853_instype.id
   
and r_rp1853_instype.maininscl in ('WEL','UCS',''--สิทธิ UC
where t_visit.f_visit_type_id = '0' --เฉพาะผู้ป่วยนอก
and t_visit.f_visit_status_id <> '4' --รายการ visit ไม่ถูกยกเลิก
and substring(t_visit.visit_begin_visit_time,1,10) between '2552-10-01' and '2553-09-30';
4. และจากโจทย์จะต้องมีความดันเช้ามาเกี่ยวข้อง เราก็ Join ตาราง t_visit_vital_sign เพิ่มเติมได้เลยค่ะ แต่ต้องวัดความดันนะคะ
select t_visit.t_visit_id, t_visit.visit_vn, substring(t_visit.visit_begin_visit_time,1,10) ,icd_dm.diag_icd10_number,icd_ht.diag_icd10_number,r_rp1853_instype.maininscl, t_visit_vital_sign.visit_vital_sign_blood_presure
from t_visit inner join t_diag_icd10 as icd_dm --แทนตารางเบาหวาน
    on (t_visit.t_visit_id = icd_dm.diag_icd10_vn
    and icd_dm.diag_icd10_active = '1' --รายการ ICD-10 ไม่ถูกยกเลิก
    and upper(substring(icd_dm.diag_icd10_number,1,3)) between 'E10' and 'E14' ) --เบาหวาน
 inner join t_diag_icd10 as icd_ht --แทนตารางความดัน
    on (t_visit.t_visit_id = icd_ht.diag_icd10_vn
    and icd_ht.diag_icd10_active = '1' --รายการ ICD-10 ไม่ถูกยกเลิก
    and upper(substring(icd_ht.diag_icd10_number,1,3)) between 'I10' and 'I15') --ความดัน
inner join t_visit_payment --สิทธิที่ผู้รับบริการใช้ในการรับบริการ
   
on t_visit.t_visit_id = t_visit_payment.t_visit_id
   
and t_visit_payment.visit_payment_active = '1' --จะต้องไม่ถูกยกเลิก
inner join b_contract_plans
   
on t_visit_payment.b_contract_plans_id = b_contract_plans.b_contract_plans_id
inner join r_rp1853_instype
  
  on b_contract_plans.r_rp1853_instype_id = r_rp1853_instype.id
   
and r_rp1853_instype.maininscl in ('WEL','UCS',''--สิทธิ UC
inner join t_visit_vital_sign
   
on t_visit.t_visit_id = t_visit_vital_sign.t_visit_id
   
and t_visit_vital_sign.visit_vital_sign_active = '1' --รายการไม่ถูกยกเลิก
   
and t_visit_vital_sign.visit_vital_sign_blood_presure <> '' --ต้องมีการวัดความดันเท่านั้น
where t_visit.f_visit_type_id = '0' --เฉพาะผู้ป่วยนอก
and t_visit.f_visit_status_id <> '4' --รายการ visit ไม่ถูกยกเลิก
and substring(t_visit.visit_begin_visit_time,1,10) between '2552-10-01' and '2553-09-30';
5. แต่ผลที่ต้องการ เราต้องการเฉพาะที่มีความดัน <= 130/80 งั้นก็มาตรวจสอบเพิ่มเติมเลยค่ะ 
select t_visit.t_visit_id, t_visit.visit_vn, substring(t_visit.visit_begin_visit_time,1,10) ,icd_dm.diag_icd10_number,icd_ht.diag_icd10_number,r_rp1853_instype.maininscl, t_visit_vital_sign.visit_vital_sign_blood_presure,cast(substring(t_visit_vital_sign.visit_vital_sign_blood_presure,1,(position('/' in t_visit_vital_sign.visit_vital_sign_blood_presure)-1)) as numeric) as bp1,cast(substring(t_visit_vital_sign.visit_vital_sign_blood_presure,(position('/' in t_visit_vital_sign.visit_vital_sign_blood_presure)+1)) as numeric) as bp2
from t_visit inner join t_diag_icd10 as icd_dm --แทนตารางเบาหวาน
    on (t_visit.t_visit_id = icd_dm.diag_icd10_vn
    and icd_dm.diag_icd10_active = '1' --รายการ ICD-10 ไม่ถูกยกเลิก
    and upper(substring(icd_dm.diag_icd10_number,1,3)) between 'E10' and 'E14' ) --เบาหวาน
 inner join t_diag_icd10 as icd_ht --แทนตารางความดัน
    on (t_visit.t_visit_id = icd_ht.diag_icd10_vn
    and icd_ht.diag_icd10_active = '1' --รายการ ICD-10 ไม่ถูกยกเลิก
    and upper(substring(icd_ht.diag_icd10_number,1,3)) between 'I10' and 'I15') --ความดัน 
inner join t_visit_payment --สิทธิที่ผู้รับบริการใช้ในการรับบริการ
   
on t_visit.t_visit_id = t_visit_payment.t_visit_id
   
and t_visit_payment.visit_payment_active = '1' จะต้องไม่ถูกยกเลิก
inner join b_contract_plans
   
on t_visit_payment.b_contract_plans_id = b_contract_plans.b_contract_plans_id
inner join r_rp1853_instype
  
  on b_contract_plans.r_rp1853_instype_id = r_rp1853_instype.id
   
and r_rp1853_instype.maininscl in ('WEL','UCS',''--สิทธิ UC
inner join t_visit_vital_sign
   
on t_visit.t_visit_id = t_visit_vital_sign.t_visit_id  
    and t_visit_vital_sign.visit_vital_sign_active = '1' --รายการไม่ถูกยกเลิก  
    and t_visit_vital_sign.visit_vital_sign_blood_presure <> '' --ต้องมีการวัดความดันเท่านั้น
where t_visit.f_visit_type_id = '0' --เฉพาะผู้ป่วยนอก
and t_visit.f_visit_status_id <> '4' --รายการ visit ไม่ถูกยกเลิก 
and cast(substring(t_visit_vital_sign.visit_vital_sign_blood_presure,1,(position('/' in t_visit_vital_sign.visit_vital_sign_blood_presure)-1)) as numeric) <= 130 --ช่วงบนน้องกว่าเท่ากับ 130
and cast(substring(t_visit_vital_sign.visit_vital_sign_blood_presure,(position('/' in t_visit_vital_sign.visit_vital_sign_blood_presure)+1)) as numeric) <= 80 --ช่วงล่างน้อยกว่าเท่ากับ 80
and substring(t_visit.visit_begin_visit_time,1,10) between '2552-10-01' and '2553-09-30';
6. หลังจากที่ได้ตามเงื่อนไขโจทย์ที่กำหนดมาแล้ว เราก็ทำส่วนสุดท้าย คือการนับยอดซึ่งตรงนี้หากนับคน เราต้องนับตาม t_patient_id และ หากต้องการนับครั้ง เราต้องนับตาม t_visit_id ซึ่งผลลัพธ์จากที่เราได้ทำ Query มานั้นอาจจะเกิดเหตุการณ์เบิ้ล Record ได้ เราสามารถนำ Distinct เข้ามาช่วยในการนับแบบไม่ซ้ำได้ ดังนี้
select count(distinct t_visit.t_patient_id) as count_pat, count(distinct t_visit.t_visit_id) as count_visit
from t_visit inner join t_diag_icd10 as icd_dm --แทนตารางเบาหวาน
    on (t_visit.t_visit_id = icd_dm.diag_icd10_vn
    and icd_dm.diag_icd10_active = '1' --รายการ ICD-10 ไม่ถูกยกเลิก
    and upper(substring(icd_dm.diag_icd10_number,1,3)) between 'E10' and 'E14' ) --เบาหวาน
 inner join t_diag_icd10 as icd_ht --แทนตารางความดัน
    on (t_visit.t_visit_id = icd_ht.diag_icd10_vn
    and icd_ht.diag_icd10_active = '1' --รายการ ICD-10 ไม่ถูกยกเลิก
    and upper(substring(icd_ht.diag_icd10_number,1,3)) between 'I10' and 'I15') --ความดัน 
inner join t_visit_payment --สิทธิที่ผู้รับบริการใช้ในการรับบริการ
   
on t_visit.t_visit_id = t_visit_payment.t_visit_id
   
and t_visit_payment.visit_payment_active = '1' จะต้องไม่ถูกยกเลิก
inner join b_contract_plans
   
on t_visit_payment.b_contract_plans_id = b_contract_plans.b_contract_plans_id
inner join r_rp1853_instype
  
  on b_contract_plans.r_rp1853_instype_id = r_rp1853_instype.id
   
and r_rp1853_instype.maininscl in ('WEL','UCS',''--สิทธิ UC
inner join t_visit_vital_sign
   
on t_visit.t_visit_id = t_visit_vital_sign.t_visit_id  
    and t_visit_vital_sign.visit_vital_sign_active = '1' --รายการไม่ถูกยกเลิก  
    and t_visit_vital_sign.visit_vital_sign_blood_presure <> '' --ต้องมีการวัดความดันเท่านั้น
where t_visit.f_visit_type_id = '0' --เฉพาะผู้ป่วยนอก
and t_visit.f_visit_status_id <> '4' --รายการ visit ไม่ถูกยกเลิก 
and cast(substring(t_visit_vital_sign.visit_vital_sign_blood_presure,1,(position('/' in t_visit_vital_sign.visit_vital_sign_blood_presure)-1)) as numeric) <= 130 --ช่วงบนน้องกว่าเท่ากับ 130
and cast(substring(t_visit_vital_sign.visit_vital_sign_blood_presure,(position('/' in t_visit_vital_sign.visit_vital_sign_blood_presure)+1)) as numeric) <= 80 --ช่วงล่างน้อยกว่าเท่ากับ 80
and substring(t_visit.visit_begin_visit_time,1,10) between '2552-10-01' and '2553-09-30';