BMS-HOSxP Community
HOSxP => การเขียน SQL Script => ข้อความที่เริ่มโดย: sumkiat ที่ ธันวาคม 09, 2011, 12:45:20 PM
-
คือ ต้องการหาว่าผู้ป่วยมาโรงพยาบาลครั้งหลังสุด วันที่ ?
ที่ลองทำ ใช้ table patient เชื่อมกับ vn_stat
ตาม code
select a.hn,b.vstdate from patient a left outer join vnstat on a.hn=b.hn group by hn order by hn
ปรากฎว่า ได้เป็น วันที่มาโรงพยาบาลครั้งแรก
ถ้าต้องการรายการสุดท้ายของแต่ละ hn ต้องเขียน Code อย่างไร
-
คือ ต้องการหาว่าผู้ป่วยมาโรงพยาบาลครั้งหลังสุด วันที่ ?
ที่ลองทำ ใช้ table patient เชื่อมกับ vn_stat
ตาม code
select a.hn,b.vstdate from patient a left outer join vnstat on a.hn=b.hn group by hn order by hn
ปรากฎว่า ได้เป็น วันที่มาโรงพยาบาลครั้งแรก
ถ้าต้องการรายการสุดท้ายของแต่ละ hn ต้องเขียน Code อย่างไร
ลองแบบนี้ครับ
select hn,max(vstdate) as vstdate from vn_stat
group by hn
order by hn desc
หรือ
select p.hn,max(v.vstdate) as vstdate from patient p
left outer join vn_stat v on v.hn=p.hn
group by p.hn
order by p.hn desc
-
มีปัญหาเพิ่มอีกหน่อย
ถ้าผมเพิ่มฟิลด์ age_y ที่อยู่ใน vn_stat
เป็นดังข้างล่าง
select p.hn,max(v.vstdate) as vstdate,v.age_y from patient p
left outer join vn_stat v on v.hn=p.hn
group by p.hn
order by p.hn desc
ปัญหาที่พบคือ คือ max(v.vstdate) จะได้เป็นข้อมูล record ท้ายสุดของแต่ละ hn
แต่ age_y ไม่ใช่ record เดียวกับ v.vstdate
คือถ้าต้องการ age_y recod เดียวกับ max(v.vstdate) จะเขียนอย่างไร
-
max(v.age_y)
-
max(v.age_y)
ตาม อ.nahos ครับ
สรุปเป็น
select p.hn,max(v.vstdate) as vstdate,max(age_y) as age_y from patient p
left outer join vn_stat v on v.hn=p.hn
group by p.hn
order by p.hn desc
-
select p.hn,max(v.vstdate) as vstdate,max(age_y) as age_y from patient p
left outer join vn_stat v on v.hn=p.hn
group by p.hn
order by p.hn desc
ลอง test แล้ว พบข้อผิดพลาดคือ ถ้า age_y ตัวข้อมูลไม่ได้เรียงตามลำดับจากน้อยไปหามาก
เช่น hn 3555 วัดเกิดผิด เดิมอายุ 20 ปี เมือเดือน พย. แต่มาตรวจใหม่ ณ ธค. จึงแก้วันเกิดให้ลดลง
อาจเหลือ 17 ปี ถ้า run sql code นี้ ก็จะได้
3555, 2011-12-01, 20
แต่คำตอบที่ต้องการคือ
3555, 2011-12-01, 17 เพราะนี่คือรายการสุดท้าย
คือถ้ามีการนำฟิลด์อื่นที่อยู่ใน vn_stat มาแสดงด้วย ก็จะทำให้ไม่ได้ข้อมูลรายการสุดท้าย
(โปรดช่วยต่ออีกหน่อย)
-
select p.hn,max(v.vstdate) as vstdate,max(age_y) as age_y from patient p
left outer join vn_stat v on v.hn=p.hn
group by p.hn
order by p.hn desc
ลอง test แล้ว พบข้อผิดพลาดคือ ถ้า age_y ตัวข้อมูลไม่ได้เรียงตามลำดับจากน้อยไปหามาก
เช่น hn 3555 วัดเกิดผิด เดิมอายุ 20 ปี เมือเดือน พย. แต่มาตรวจใหม่ ณ ธค. จึงแก้วันเกิดให้ลดลง
อาจเหลือ 17 ปี ถ้า run sql code นี้ ก็จะได้
3555, 2011-12-01, 20
แต่คำตอบที่ต้องการคือ
3555, 2011-12-01, 17 เพราะนี่คือรายการสุดท้าย
คือถ้ามีการนำฟิลด์อื่นที่อยู่ใน vstdate มาแสดงด้วย ก็จะทำให้ไม่ได้ข้อมูลรายการสุดท้าย
(โปรดช่วยต่ออีกหน่อย)
งั้นลองแบบนี้ครับ
select p.hn,max(v.vstdate) as vstdate,timestampdiff(year,p.birthday,max(v.vstdate)) as count_year from patient p
left outer join vn_stat v on v.hn=p.hn
group by p.hn
order by p.hn desc
หรือแบบนี้กรณีเอาเฉพาะผู้ที่เคยมารับบริการที่โรงพยาบาลครับ
select p.hn,max(v.vstdate) as vstdate,timestampdiff(year,p.birthday,max(v.vstdate)) as count_year from patient p
left outer join vn_stat v on v.hn=p.hn
where p.hn in (select hn from ovst)
group by p.hn
order by p.hn desc
-
select v.hn, v.vn, v.vstdate, v.age_y
from vn_stat v
join (select v2.hn, max(v2.vstdate) max_vstdate from vn_stat v2 group by hn limit 100) temp on temp.hn=v.hn and temp.max_vstdate=v.vstdate
-
อันนี้จะดีกว่าครับ เผื่อมี 2 visit ใน 1 วัน จะได้แสดง visit ล่าสุดจริง ๆ
select v.hn, v.vn, v.vstdate, v.age_y
from vn_stat v
join (select v2.hn, max(v2.vn) max_vn from vn_stat v2 group by hn limit 1000) temp on temp.hn=v.hn and temp.max_vn=v.vn
-
คือถ้ามีการนำฟิลด์อื่นที่อยู่ใน vstdate มาแสดงด้วย ก็จะทำให้ไม่ได้ข้อมูลรายการสุดท้าย
(โปรดช่วยต่ออีกหน่อย)
งั้นลองแบบนี้ครับ
select p.hn,max(v.vstdate) as vstdate,timestampdiff(year,p.birthday,max(v.vstdate)) as count_year from patient p
left outer join vn_stat v on v.hn=p.hn
group by p.hn
order by p.hn desc
หรือแบบนี้กรณีเอาเฉพาะผู้ที่เคยมารับบริการที่โรงพยาบาลครับ
select p.hn,max(v.vstdate) as vstdate,timestampdiff(year,p.birthday,max(v.vstdate)) as count_year from patient p
left outer join vn_stat v on v.hn=p.hn
where p.hn in (select hn from ovst)
group by p.hn
order by p.hn desc
ตาม กอล์ฟ เลย
-
ขอรบกวนทุกท่านอีกนิดหนึ่ง
ผมขออนุญาติอธิบายและปรับโจทย์ ให้กระทัดรัด ดังนี้
คือว่า ถ้าผมมี 2 ตาราง
ตารางที่ 1 ชื่อ patient ประกอบด้วย 3 ฟิลด์
- hn
- fname
- lname
ตารางที่ 2 ชือ vn_stat ประกอบด้วย 5 ฟิลด์
- hn
- vstdate
- age_y
- age_m
- age_d
แล้วนำ table patient เชื่อมกับ vn_stat
ได้ code
select a.hn,a.fname,a.lname,b.vstdate,b.age_y,b.age_m
from patient a left outer join vnstat on a.hn=b.hn group by hn order by hn
มีเงื่อนไขคือให้ใช้ฟิลด์ เฉพาะที่ระบุ ใน 2 ตารางด้านบน เท่านั้น
เพิ่อหารายการล่าสุดของคนใข้แต่ละคน นั้นคือการหารายการสุดท้ายของแต่ละ hn ใน vn_stat
ถามว่าจะสามารถหาได้ไหม
ถ้าได้จะเขียน code อย่างไร
-
อยากรู้ครับว่าต้องการเอาข้อมูลไปทำอะไรต่อครับ
-
จะเอา code นี้ไปทำอะไรครับ ???
code ที่ อ.udomchok เขียนไว้ก็ได้ครับ เพราะ เอา max vn มาใช้แล้ว
select v.hn, v.vn, v.vstdate, v.age_y ,v.age_m,p.lname,p.fname
from vn_stat v
left join patient p on p.hn=v.hn
join (select v2.hn, max(v2.vn) max_vn from vn_stat v2 group by hn limit 1000)
temp on temp.hn=v.hn and temp.max_vn=v.vn
-
คือ เคยเจอโจทย์ ลักษณะคล้าย กับที่อธิบายมา
กับอีกฐานข้อมูล จำนวนฟิลด์ น้อยกว่าใน hosxp
ซึ่งมันนานมาแล้ว แต่ก็ยังแก้ไขไม่ได้ ก็นานจนลืม
แล้วตอนนี้ ก็ได้โจทย์ ตามที่อธิบายไป
ก็ใช้ left outer join กับ group by มันก็น่าจะตอบโจทย์ได้แล้ว
แต่ การ group by ใน mysql ค่าที่ได้ถ้าซ้ำ ก็จะไปเลือกเอารายการแรก
จึงอยากรู้ว่า จะทำอย่างไร ให้ใช้ group by ถ้าซ้ำ แล้วไปหยิบเอารายการสุดท้ายแทน
เพราะผมรู้สึกว่า มันอีกแค่นิดเดียว
คือไม่อยากเขียนยาวๆ แต่ถ้าไม่ได้จริงๆ ก็คงต้องเขียน code ยาวๆ ตามที่ทุกท่านได้ post มา
-
hosxp จะ stamp วันที่มารับบริการครั้งสุดท้าย last_visit ไว้ที่ ตาราง patient อยู่แล้วครับ :) :)
-
คือ เคยเจอโจทย์ ลักษณะคล้าย กับที่อธิบายมา
กับอีกฐานข้อมูล จำนวนฟิลด์ น้อยกว่าใน hosxp
ซึ่งมันนานมาแล้ว แต่ก็ยังแก้ไขไม่ได้ ก็นานจนลืม
แล้วตอนนี้ ก็ได้โจทย์ ตามที่อธิบายไป
ก็ใช้ left outer join กับ group by มันก็น่าจะตอบโจทย์ได้แล้ว
แต่ การ group by ใน mysql ค่าที่ได้ถ้าซ้ำ ก็จะไปเลือกเอารายการแรก
จึงอยากรู้ว่า จะทำอย่างไร ให้ใช้ group by ถ้าซ้ำ แล้วไปหยิบเอารายการสุดท้ายแทน
เพราะผมรู้สึกว่า มันอีกแค่นิดเดียว
คือไม่อยากเขียนยาวๆ แต่ถ้าไม่ได้จริงๆ ก็คงต้องเขียน code ยาวๆ ตามที่ทุกท่านได้ post มา
พี่ครับ จะเอาไปทำอะไรครับ
-
อยากลองดูว่าจะเขียน code ให้สั้นๆ ได้ไหม ?
-
select hn from patient คำสั่งเดียวครับ
ทีนี้ใน report designer วาง variable ชนิด date ลงไปหนึ่งตัว แล้วใช้คำสั่ง
value:=GetSQLDateData('select vstdate from vn_stat where hn="'+datapipeline['hn']+'" order by vstdate desc limit 1');
-
ลองทดสอบมั้ง
SELECT vs.hn,vs.vstdate,vs.age_y,vs.age_m,vs.age_d,
p.hn,p.fname,p.lname
FROM (SELECT * FROM vn_stat ORDER BY vstdate DESC) AS vs
INNER JOIN patient p ON p.hn = vs.hn
GROUP BY vs.hn
-
SELECT vs.hn,vs.vstdate,vs.age_y,vs.age_m,vs.age_d,
concat(p.pname,p.fname,' ',p.lname) as ptname,vs.vn,vs.pdx,vs.cid,vs.income
FROM (SELECT * FROM vn_stat ORDER BY vstdate DESC) AS vs
INNER JOIN patient p ON p.hn = vs.hn
GROUP BY vs.hn
เพิ่มรายละเอียด.....อิอิอิอิ....