วันนี้เพิ่งได้ trick มา
แบบนี้ใช่ไหมที่เรียกว่า select ซ้อน select
select o.vn, o.an, o.icode, o.rxdate
from opitemrece o
where o.icode in (select icode from drugitem where name like "paracet%") and o.rxdate bewteen "2009-10-01" and "2010-09-30"
ข้อดีคือส่ง sql นี้ไป ใช้ได้ทุก ร.พ. ก็จะได้ข้อมูลการใช้ยา paracet ทุกรูปแบบ เม็ด น้ำ ฉีด...
ลอง run เปรียบเทียบกับ
select o.vn, o.an, o.icode, o.rxdate
from opitemrece o
where o.icode in ("1xxxxxxx","1zzzzzzzz","1vvvvvvvv","1aaaaaaa","1cccccccc") and o.rxdate bewteen "2009-10-01" and "2010-09-30"
จะเห็นว่าแบบที่ 2 เร็วกว่า อย่างเห็นได้ชัด แต่แบบที่สองมีข้อเสียคือต้องรู้ icode ของยานั้น คือต้องแก้ไข sql ให้ถูก
แบบที่สาม ใช้ join กับ temp table
select o.vn, o.an, o.icode, o.rxdate
from opitemrece o
join (select icode from drugitem where name like "paracet%") as temp on temp.icode=o.icode
where o.rxdate bewteen "2009-10-01" and "2010-09-30"
ผมลองกับข้อมูล Lab จำนวนมาพบว่าแบบที่สามนี่เร็วมาก ๆ ครับ
โจทย์คือต้องการทราบว่าผู้ป่วยที่ใช้ยา xxxx มีตรวจ lab อะไรบ้าง ยา xxxx มี icode หลายตัว เนื่องจากมีหลายรูปแบบและหลายความแรง
เอาแค่นี้ก่อน
ผมก็เขียน sql ดึงข้อมูลแบบนี้
select distinct if(o.vn is null,a.vn,o.vn) as vn
from opitemrece o
where o.icde in (select icode from drugitems where name like "xxxxx%")
and o.rxdate between "2009-10-01' and "2010-09-30"
เพื่อดึงว่ามี vn ไหนบ้างที่ใช้ยานี้ ก็ได้ VN ออกมา เพื่อเอาไปเชื่อมกับข้อมูลการสั่ง LAB จาก lab_order_service
ถ้าใช้ select ซ้อน select ก็จะเขียนแบบนี้ครับ
select * from lab_order_service where vn in (
select distinct if(o.vn is null,a.vn,o.vn) as vn
from opitemrece o
where o.icde in (select icode from drugitems where name like "xxxxx%")
and o.rxdate between "2009-10-01' and "2010-09-30")
จะเห็นว่ามี select ซ้อน select ซ้อนอยู่ใน select อีกที 3 ชั้น
อันนี้ run ช้ามาก
หากเปลี่ยนเป็น
select * from lab_order_service where vn in (
select distinct if(o.vn is null,a.vn,o.vn) as vn
from opitemrece o
where o.icde in ("1zzzzzz","1xxxxxx","1cccccc","1vvvvvv","1aaaaaa")
and o.rxdate between "2009-10-01' and "2010-09-30")
จะ run ได้เร็วขึ้นอีกหน่อย
ลองเปลี่ยนมาเป็นแบบนี้ครับเร็วขึ้น
select los.*
from lab_order_service los
join
(select distinct if(o.vn is null,a.vn,o.vn) as vn
from opitemrece o
where o.icde in ("1zzzzzz","1xxxxxx","1cccccc","1vvvvvv","1aaaaaa")
and o.rxdate between "2009-10-01' and "2010-09-30") as temp2 on temp2.vn=los.vn
สุดท้ายเปลี่ยนมาเป็นแบบนี้ครับเร็วอย่างมากมาย
select los.*
from lab_order_service los
join
(select distinct if(o.vn is null,a.vn,o.vn) as vn
from opitemrece o
join (select icode from drugitems where name like "xxxx") as temp on temp.icode=o.icode
where o.rxdate between "2009-10-01' and "2010-09-30") as temp2 on temp2.vn=los.vn