วันเสาร์, กันยายน 03, 2548
เรื่องของ SQL ตอนที่ 3
ท้ายๆของตอนที่ 2 ได้เกริ่นไว้ว่าจะมาพูดต่อเรื่องของน้องจอย (JOIN) กว่าจะได้เริ่มก็ล่วงเลยมาจนถึงวันนี้ เนื่องจากมัวไปทำบล็อกอยู่ที่ blogger dot com ซะนานจนถึงเมื่อคืนก็ลงตัวจนได้ ความจริงถ้าผมไม่เรื่องมากก็เสร็จไปนานแล้วล่ะ คือเรื่องราวมีอยู่ว่าไม่ค่อยชอบใจ template ที่ blogger ให้มาสักเท่าไหร่ก็เลยไปหาที่ถูกใจเอาใหม่ที่ blogger-templates dot com แต่ก็ต้องมานั่งแก้ไข CSS (Cascade Style Sheet) อยู่นาน ความที่เป็นเรื่องที่ยังไม่ได้เรียนรู้ กว่าจะเข้าใจอะไรสักอย่างก็ต้องทุ่มทุนสร้างยอมนั่งแกะโค๊ดของ CSS เปิดเน็ตไปด้วยค้นหาข้อมูลไปด้วย กว่าจะพอใจก็ตีหนึ่งเข้าไปแล้ว แถมไม่พอตอนเช้าวันนี้ก็ต้องไปประชุมผู้ปกครองที่โรงเรียนอัยยสิริ (โรงเรียนที่ลูกสาวของผมเรียนอยู่) อีกครึ่งค่อนวันกลับมาว่าจะลุยต่อ ฝนเจ้ากรรมดันตกลงมาหนัก ทำเอาไฟดับไปทั้งเมือง ปาเข้าไปตั้งสามโมงกว่าถึงจะมาได้
เพื่อไม่ให้เป็นการเสียเวลา เริ่มกันเลย
การ JOIN เนี่ยปกติแล้วเค้าใช้ทำกับตารางนะครับ ไม่ใช่ทำกับดาต้าเบส ประมาณว่าเอาตารางตั้งแต่สองตารางมาเชื่อมโยงกัน โดยอาศัยคีย์หลักอันใดอันหนึ่ง ซึ่งก็หมายความว่าทั้งสองตารางนั้นอย่างน้อยที่สุดต้องมีฟิลด์ใดฟิลด์หนึ่งเหมือนกัน ตารางนี่อาจเป็นได้ทั้งตารางที่มีอยู่จริง หรือจะเป็นตารางที่ได้จากการคิวรี่ออกมาจาก SQL ก็ได้นะครับ
ยกตัวอย่างดีกว่า จะได้เห็นภาพกันชัดๆ เกิดว่าผู้บริหารอยากทราบว่าวันนี้มีผู้ป่วยมารับบริการกี่คน จำแนกตามสิทธิบัตร ? ก็เขียนเป็น SQL ได้ดังนี้ สมมติอีกแล้วว่าให้เป็นชุดที่หนึ่ง
Concept
คงพอจะมองเห็นภาพ LEFT JOIN กันคร่าวๆ ไปบ้างแล้วนะครับ เมื่อ LEFT JOIN สองตารางได้ ก็น่าจะ JOIN 3,4 .... ไปได้เรื่อยๆ ถ้าเราจับหลักตรงนี้ได้ ;-) จะสักร้อยก็คงไม่มีปัญหาอะไร จริงไหม เอางี้ดีกว่าผมมีโจทย์อยากให้ลองคิดกันเล่นๆ ว่าถ้าอยากจะทราบว่าในวันที่ 15 กรกฏาคม 2548 มีผู้ป่วยนอกมารับบริการแยกเพศ ชาย,หญิง,รวม จำแนกตามสิทธิบัตร(เอาสิทธิบัตรออกมาให้หมดนะ) อาจจะ comment ในบล็อกเลยก็ได้ หรือจะส่ง SQL มาให้ผมทางเมล์ หรือจะไปโพสต์ที่เวบ ในส่วนของ เรื่องการออกรายงาน ก็ได้ ลองคิดกันดูนะครับ ผมแนะให้นิดนึงก่อน ว่ามีตาราง t_patient เพิ่มเข้ามาอีก 1 ตาราง
แหล่งความรู้และอ้างอิง
All about cars
[url=http://cheap-car-rental.yourgoldhost.org] cheap car rental [/url]
[url=http://car-donation.yourgoldhost.org] car donation [/url]
[url=http://hybrid-car.yourgoldhost.org] hybrid car [/url]
[url=http://online-car-insurance.yourgoldhost.org] online car insurance [/url]
[url=http://car-price.yourgoldhost.org] car price [/url]
[url=http://muscle-car.yourgoldhost.org] muscle car [/url]
[url=http://new-car.yourgoldhost.org] new car [/url]
[url=http://nissan-car.yourgoldhost.org] nissan car [/url]
แสดงความคิดเห็น
Powered for เพื่อไม่ให้เป็นการเสียเวลา เริ่มกันเลย
การ JOIN เนี่ยปกติแล้วเค้าใช้ทำกับตารางนะครับ ไม่ใช่ทำกับดาต้าเบส ประมาณว่าเอาตารางตั้งแต่สองตารางมาเชื่อมโยงกัน โดยอาศัยคีย์หลักอันใดอันหนึ่ง ซึ่งก็หมายความว่าทั้งสองตารางนั้นอย่างน้อยที่สุดต้องมีฟิลด์ใดฟิลด์หนึ่งเหมือนกัน ตารางนี่อาจเป็นได้ทั้งตารางที่มีอยู่จริง หรือจะเป็นตารางที่ได้จากการคิวรี่ออกมาจาก SQL ก็ได้นะครับ
ยกตัวอย่างดีกว่า จะได้เห็นภาพกันชัดๆ เกิดว่าผู้บริหารอยากทราบว่าวันนี้มีผู้ป่วยมารับบริการกี่คน จำแนกตามสิทธิบัตร ? ก็เขียนเป็น SQL ได้ดังนี้ สมมติอีกแล้วว่าให้เป็นชุดที่หนึ่ง
ก็ได้ผลลัพท์ดังนี้
SELECT
b_contract_plans.contract_plans_number
,b_contract_plans.contract_plans_description
,COUNT(t_visit.t_visit_id) AS total
FROM
b_contract_plans,t_visit,t_visit_payment
WHERE
t_visit.t_visit_id=t_visit_payment.t_visit_id
AND t_visit_payment.b_contract_plans_id=b_contract_plans.b_contract_plans_id
AND t_visit.f_visit_type_id='0'
AND t_visit.f_visit_status_id='3'
AND (SUBSTRING(t_visit.visit_financial_discharge_time,0,11) BETWEEN '2548-07-01' and '2548-07-01')
GROUP BY
b_contract_plans.contract_plans_number
,b_contract_plans.contract_plans_description
ถุกต้องตามตำราเป๊ะ ไม่มีอะไรที่ผิดพลาดอีกแล้ว สังเกตุนิดนึงนะว่าสิทธิบัตรที่เรามีอยู่จริงน่ะมันมีเยอะกว่านี้มาก แต่ทำไมผลการคิวรี่ที่ได้มาน่ะ สิทธิบัตรทำไมออกมาไม่ครบ ถ้าผู้บริหารไม่ซีเรียส ก็ไม่มีอะไรทำต่อแล้ว แต่ถ้า....... เราก็ต้องทำให้สิทธิบัตรน่ะแสดงออกมาจนครบถึงแม้ว่าผลการนับจำนวนจะเป็นศูนย์ก็ตาม อืมอาจมีวิธีทำได้อย่างน้อยคือวิธีที่จะนำเสนอดังต่อไปนี้
AC บัตรทองมี ท (นักเรียนมัธยมต้น) 1
AG บัตรทองมี ท (ผู้สูงอายุ) 20
A11 ผู้ประสบภัยจากรถ (หลักฐานครบ) 1
A71 บัตรประกันสังคม (คู่สัญญา) 1
AJ บัตรทองมี ท (ผู้นำชุมชน) 1
UC1 บัตรทองเสียค่าธรรมเนียม 32
AA บัตรทองมี ท (เด็ก 0-5 ปี) 12
A76 บัตรประกันสังคม (ไม่ใช่คู่สัญญา ชำระเงินเอง) 1
A21 เบิกได้ (ข้าราชการ/ลูกจ้างประจำ) 12
UC2 บัตรทองเสียค่าธรรมเนียม (นอกเครือข่าย ชำระเงินเอง) 1
AB บัตรทองมี ท (ผู้มีรายได้น้อย) 45
AK2 บัตรทองมี ท (อสม นอกเขตอำเภอ) 2
AF บัตรทองมี ท (สมณเพศ) 1
A1 ชำระเงินเอง 1
AK1 บัตรทองมี ท (อสม ในเขตอำเภอ) 7
AA1 บัตรทองมี ท (เด็ก 6-12 ปี) 12
- การจะทำให้สิทธิบัตรแสดงออกมาหมดเนี่ยมันไม่ยากหรอกเราก็
SELECT
b_contract_plans.contract_plans_number
,b_contract_plans.contract_plans_description
FROM
b_contract_plans
ผลลัพท์ก็ได้ออกมาเป็นอย่างนี้
A1 ชำระเงินเอง
A72 บัตรประกันสังคม (คลอด ชำระเอง)
A76 บัตรประกันสังคม (ไม่ใช่คู่สัญญา ชำระเงินเอง)
AH2 บัตรทองมี ท (นอกเครือข่าย ชำระเงินเอง)
AH5 บัตรแรงงานต่างด้าว (นอกเครือข่าย)
AH6 บัตรทองมี ท (ในเครือข่าย ชำระเงินเอง)
UC2 บัตรทองเสียค่าธรรมเนียม (นอกเครือข่าย ชำระเงินเอง)
UC4 บัตรทองเสียค่าธรรมเนียม (ในเครือข่าย ชำระเงินเอง)
A21 เบิกได้ (ข้าราชการ/ลูกจ้างประจำ)
A22 เบิกได้ (รัฐวิสาหกิจ,ส่วนท้องถิ่น)
A73 บัตรประกันสังคม (ญาติสายตรง)
A74 บัตรประกันสังคม (เจ้าหน้าที่โรงพยาบาล)
AK1 บัตรทองมี ท (อสม ในเขตอำเภอ)
A71 บัตรประกันสังคม (คู่สัญญา)
AA บัตรทองมี ท (เด็ก 0-5 ปี)
AB บัตรทองมี ท (ผู้มีรายได้น้อย)
AC บัตรทองมี ท (นักเรียนมัธยมต้น)
AE บัตรทองมี ท (ทหารผ่านศึก)
AD บัตรทองมี ท (ผู้พิการ)
AG บัตรทองมี ท (ผู้สูงอายุ)
AH บัตรทองมี ท (บัตรชั่วคราว)
AH1 บัตรทองมี ท (พอสว)
AH3 บัตรทองมี ท (นอกเครือข่ายฉุกเฉิน)
AH4 บัตรแรงงานต่างด้าว (ในเครือข่าย)
AJ บัตรทองมี ท (ผู้นำชุมชน)
AK2 บัตรทองมี ท (อสม นอกเขตอำเภอ)
UC1 บัตรทองเสียค่าธรรมเนียม
UC3 บัตรทองเสียค่าธรรมเนียม (นอกเครือข่ายฉุกเฉิน)
AF บัตรทองมี ท (สมณเพศ)
AZ สังคมสงเคราะห์
A75 บัตรประกันสังคม (ทำฟัน ชำระเอง)
AA1 บัตรทองมี ท (เด็ก 6-12 ปี)
A11 ผู้ประสบภัยจากรถ (หลักฐานครบ)
A12 ผู้ประสบภัยจากรถ (หลักฐานไม่ครบ)
ซะก็สิ้นเรื่อง สมมติให้ SQL นี้เป็นชุดที่สอง - ก็ได้สองตารางตามที่เกริ่นให้ฟังมาแล้วคือ ตารางที่ได้จากการคิวรี่จาก SQL ชุดที่หนึ่ง และตารางที่ได้จากการคิวรี่จาก SQL ชุดที่สอง อ๊ะๆ เริ่มเข้าเค้าแล้วล่ะนะ ทีนี้เราก็เอาตารางสองตารางนี้มา JOIN กันโดยอาศัย สิ่งสองตารางนี้มีเหมือนกันคือ b_contract_plans.contract_plans_number แล้วจะเริ่มยังงัยดีล่ะ โจทย์ของเราก็คือต้องการแสดงสิทธิบัตรทั้งหมดออกมา ก็น่าจะใช้ SQL ชุดที่สองมาก่อน แล้วเอาชุดที่หนึ่งมา JOIN โดยใช้ b_contract_plans.contract_plans_number เป็นพ่อสื่อพ่อชักให้
- การ JOIN ตารางนั้นมีหลายรูปแบบ หลายท่านอาจจะไม่ทราบว่า SQL ที่คิวรี่ข้อมูลจากหลายตารางนั้นน่ะมีการ join กันอยู่แล้วดูจากตรง WHERE เช่น
จาก SQL ชุดที่หนึ่ง อันนีี้ก็เรียกว่า JOIN เหมือนกันแต่เป็นการ JOIN แบบธรรมดาที่สุด (INNER JOIN) แต่สิ่งที่เราจะทำกันต่อไปนี้เรียกว่า LEFT JOIN คือเอาตารางแรก ที่อยู่ทางซ้ายเป็นหลัก แล้วเอาตารางที่สองมา JOIN เราลองมาร่างดูคร่าวๆ ก่อนแล้วกัน
WHERE
t_visit.t_visit_id=t_visit_payment.t_visit_id
AND t_visit_payment.b_contract_plans_id=b_contract_plans.b_contract_plans_id
ได้ผลลัพท์ดังนี้
SELECT
b_contract_plans.contract_plans_number
,b_contract_plans.contract_plans_description
FROM
(b_contract_plans LEFT JOIN
(
SQL ชุดที่หนึ่ง
) AS temp1(ชื่อที่เราสมมติขึ้นมา) ON b_contract_plans.contract_plans_number = temp1.contract_plans_number )
โฮ่ เกิดอะไรขึ้นกลับไปดู SQL ที่เราร่างๆไว้ก็ถึงอ้อ คือว่าเรายังไม่ได้กำหนดให้มีการแสดงผลของการนับจาก SQL ชุดที่สองคือชุดที่เราสมมติให้ชื่อ temp1 นั่นเองรู้อย่างนี้แล้วเราก็เพิ่่ม ไปอย่างนี้ (ตามอักษรสีแดง)
A1 ชำระเงินเอง
A72 บัตรประกันสังคม (คลอด ชำระเอง)
A76 บัตรประกันสังคม (ไม่ใช่คู่สัญญา ชำระเงินเอง)
AH2 บัตรทองมี ท (นอกเครือข่าย ชำระเงินเอง)
AH5 บัตรแรงงานต่างด้าว (นอกเครือข่าย)
AH6 บัตรทองมี ท (ในเครือข่าย ชำระเงินเอง)
UC2 บัตรทองเสียค่าธรรมเนียม (นอกเครือข่าย ชำระเงินเอง)
UC4 บัตรทองเสียค่าธรรมเนียม (ในเครือข่าย ชำระเงินเอง)
A21 เบิกได้ (ข้าราชการ/ลูกจ้างประจำ)
A22 เบิกได้ (รัฐวิสาหกิจ,ส่วนท้องถิ่น)
A73 บัตรประกันสังคม (ญาติสายตรง)
A74 บัตรประกันสังคม (เจ้าหน้าที่โรงพยาบาล)
AK1 บัตรทองมี ท (อสม ในเขตอำเภอ)
A71 บัตรประกันสังคม (คู่สัญญา)
AA บัตรทองมี ท (เด็ก 0-5 ปี)
AB บัตรทองมี ท (ผู้มีรายได้น้อย)
AC บัตรทองมี ท (นักเรียนมัธยมต้น)
AE บัตรทองมี ท (ทหารผ่านศึก)
AD บัตรทองมี ท (ผู้พิการ)
AG บัตรทองมี ท (ผู้สูงอายุ)
AH บัตรทองมี ท (บัตรชั่วคราว)
AH1 บัตรทองมี ท (พอสว)
AH3 บัตรทองมี ท (นอกเครือข่ายฉุกเฉิน)
AH4 บัตรแรงงานต่างด้าว (ในเครือข่าย)
AJ บัตรทองมี ท (ผู้นำชุมชน)
AK2 บัตรทองมี ท (อสม นอกเขตอำเภอ)
UC1 บัตรทองเสียค่าธรรมเนียม
UC3 บัตรทองเสียค่าธรรมเนียม (นอกเครือข่ายฉุกเฉิน)
AF บัตรทองมี ท (สมณเพศ)
AZ สังคมสงเคราะห์
A75 บัตรประกันสังคม (ทำฟัน ชำระเอง)
AA1 บัตรทองมี ท (เด็ก 6-12 ปี)
A11 ผู้ประสบภัยจากรถ (หลักฐานครบ)
A12 ผู้ประสบภัยจากรถ (หลักฐานไม่ครบ)
SELECT
b_contract_plans.contract_plans_number
,b_contract_plans.contract_plans_description
,temp1.total AS total
FROM
(b_contract_plans LEFT JOIN
(
SELECT
b_contract_plans.contract_plans_number AS contract_plans_number
,b_contract_plans.contract_plans_description AS contract_plans_description
,COUNT(t_visit.t_visit_id) AS total
FROM
b_contract_plans,t_visit,t_visit_payment
WHERE
t_visit.t_visit_id=t_visit_payment.t_visit_id
AND t_visit_payment.b_contract_plans_id=b_contract_plans.b_contract_plans_id
AND t_visit.f_visit_type_id='0'
AND t_visit.f_visit_status_id='3'
AND (SUBSTRING(t_visit.visit_financial_discharge_time,0,11) BETWEEN '2548-07-01' and '2548-07-01')
GROUP BY
b_contract_plans.contract_plans_number
,b_contract_plans.contract_plans_description) AS temp1 ON b_contract_plans.contract_plans_number=temp1.contract_plans_number)
ก็ได้ผลลัพท์จากการคิวรี่ดังนี้
A1 ชำระเงินเอง 1
A11 ผู้ประสบภัยจากรถ (หลักฐานครบ) 1
A12 ผู้ประสบภัยจากรถ (หลักฐานไม่ครบ)
A21 เบิกได้ (ข้าราชการ/ลูกจ้างประจำ) 12
A22 เบิกได้ (รัฐวิสาหกิจ,ส่วนท้องถิ่น)
A71 บัตรประกันสังคม (คู่สัญญา) 1
A72 บัตรประกันสังคม (คลอด ชำระเอง)
A73 บัตรประกันสังคม (ญาติสายตรง)
A74 บัตรประกันสังคม (เจ้าหน้าที่โรงพยาบาล)
A75 บัตรประกันสังคม (ทำฟัน ชำระเอง)
A76 บัตรประกันสังคม (ไม่ใช่คู่สัญญา ชำระเงินเอง) 1
AA บัตรทองมี ท (เด็ก 0-5 ปี) 12
AA1 บัตรทองมี ท (เด็ก 6-12 ปี) 12
AB บัตรทองมี ท (ผู้มีรายได้น้อย) 45
AC บัตรทองมี ท (นักเรียนมัธยมต้น) 1
AD บัตรทองมี ท (ผู้พิการ)
AE บัตรทองมี ท (ทหารผ่านศึก)
AF บัตรทองมี ท (สมณเพศ) 1
AG บัตรทองมี ท (ผู้สูงอายุ) 20
AH บัตรทองมี ท (บัตรชั่วคราว)
AH1 บัตรทองมี ท (พอสว)
AH2 บัตรทองมี ท (นอกเครือข่าย ชำระเงินเอง)
AH3 บัตรทองมี ท (นอกเครือข่ายฉุกเฉิน)
AH4 บัตรแรงงานต่างด้าว (ในเครือข่าย)
AH5 บัตรแรงงานต่างด้าว (นอกเครือข่าย)
AH6 บัตรทองมี ท (ในเครือข่าย ชำระเงินเอง)
AJ บัตรทองมี ท (ผู้นำชุมชน) 1
AK1 บัตรทองมี ท (อสม ในเขตอำเภอ) 7
AK2 บัตรทองมี ท (อสม นอกเขตอำเภอ) 2
AZ สังคมสงเคราะห์
UC1 บัตรทองเสียค่าธรรมเนียม 32
UC2 บัตรทองเสียค่าธรรมเนียม (นอกเครือข่าย ชำระเงินเอง) 1
UC3 บัตรทองเสียค่าธรรมเนียม (นอกเครือข่ายฉุกเฉิน)
UC4 บัตรทองเสียค่าธรรมเนียม (ในเครือข่าย ชำระเงินเอง)
คงพอจะมองเห็นภาพ LEFT JOIN กันคร่าวๆ ไปบ้างแล้วนะครับ เมื่อ LEFT JOIN สองตารางได้ ก็น่าจะ JOIN 3,4 .... ไปได้เรื่อยๆ ถ้าเราจับหลักตรงนี้ได้ ;-) จะสักร้อยก็คงไม่มีปัญหาอะไร จริงไหม เอางี้ดีกว่าผมมีโจทย์อยากให้ลองคิดกันเล่นๆ ว่าถ้าอยากจะทราบว่าในวันที่ 15 กรกฏาคม 2548 มีผู้ป่วยนอกมารับบริการแยกเพศ ชาย,หญิง,รวม จำแนกตามสิทธิบัตร(เอาสิทธิบัตรออกมาให้หมดนะ) อาจจะ comment ในบล็อกเลยก็ได้ หรือจะส่ง SQL มาให้ผมทางเมล์ หรือจะไปโพสต์ที่เวบ ในส่วนของ เรื่องการออกรายงาน ก็ได้ ลองคิดกันดูนะครับ ผมแนะให้นิดนึงก่อน ว่ามีตาราง t_patient เพิ่มเข้ามาอีก 1 ตาราง
แหล่งความรู้และอ้างอิง
- John C. Worsley and Joshua D. Drake, Practical PostgreSQL
O'Reilly & Associates, Inc., CA ,USA
All about cars
[url=http://cheap-car-rental.yourgoldhost.org] cheap car rental [/url]
[url=http://car-donation.yourgoldhost.org] car donation [/url]
[url=http://hybrid-car.yourgoldhost.org] hybrid car [/url]
[url=http://online-car-insurance.yourgoldhost.org] online car insurance [/url]
[url=http://car-price.yourgoldhost.org] car price [/url]
[url=http://muscle-car.yourgoldhost.org] muscle car [/url]
[url=http://new-car.yourgoldhost.org] new car [/url]
[url=http://nissan-car.yourgoldhost.org] nissan car [/url]
แสดงความคิดเห็น


Copyright ? 2008-2009 Uthai Lueadnakrop. All Rights reserved