กระทู้เก่าบอร์ด อ.Yeadram
1,068 8
URL.หัวข้อ /
URL
สอบถามการประมวลผลข้อมูลครับ
สอบถามการประมวลผลข้อมูลครับ
ข้อมูลมีแบบตารางด้านบน
ต้องการให้ได้เป้นแบบตารางด้านล่างครับ
ข้อมูลมีแบบตารางด้านบน
ต้องการให้ได้เป้นแบบตารางด้านล่างครับ
8 Reply in this Topic. Dispaly 1 pages and you are on page number 1
2 @R19621
จากการนำไปประยุกต์ใช้ครับ
SELECT a.HN, a.VSTDATE, a.ID, a.CLINIC, a.REG, a.DCH, IIf(IsNull((SELECT Min([REG]) FROM Table1 AS b WHERE a.ID < b.ID And a.VSTDATE=b.VSTDATE And a.hn=b.hn )),[REG],(SELECT Min([REG]) FROM Table1 AS b WHERE a.ID < b.ID And a.VSTDATE=b.VSTDATE And a.hn=b.hn)) AS BF_DCH_TIME
FROM Table1 AS a
ORDER BY a.HN, a.VSTDATE, a.ID;
ได้ผลข้อมูลตามต้องการครับ แต่ไม่แน่ใจว่า SQL ถูกต้องหรือไม่ ขอความอนุเคราะห์ อาจารย์ TTT ตรวจสอบอีกครั้งครับ
การทำ Query แบบนี้เรียกว่าอะไรครับ มันเหมือน Select Query แต่มันซับซ้อน
ตรง a.HN, a.VSTDATE, a.CLINIC, a.REG, a.DCH มันมองเห็นในตาราง QBE Grid แต่ b.ID มันอยู่ตรงไหนครับมองไม่เห้น หรือลักษณะการทำงานเป็นอย่างไร เพื่อความเข้าใจและเป้นปัญญาทานครับ ขอบพระคุฯเป็นอย่างสูง
SELECT a.HN, a.VSTDATE, a.ID, a.CLINIC, a.REG, a.DCH, IIf(IsNull((SELECT Min([REG]) FROM Table1 AS b WHERE a.ID < b.ID And a.VSTDATE=b.VSTDATE And a.hn=b.hn )),[REG],(SELECT Min([REG]) FROM Table1 AS b WHERE a.ID < b.ID And a.VSTDATE=b.VSTDATE And a.hn=b.hn)) AS BF_DCH_TIME
FROM Table1 AS a
ORDER BY a.HN, a.VSTDATE, a.ID;
ได้ผลข้อมูลตามต้องการครับ แต่ไม่แน่ใจว่า SQL ถูกต้องหรือไม่ ขอความอนุเคราะห์ อาจารย์ TTT ตรวจสอบอีกครั้งครับ
การทำ Query แบบนี้เรียกว่าอะไรครับ มันเหมือน Select Query แต่มันซับซ้อน
ตรง a.HN, a.VSTDATE, a.CLINIC, a.REG, a.DCH มันมองเห็นในตาราง QBE Grid แต่ b.ID มันอยู่ตรงไหนครับมองไม่เห้น หรือลักษณะการทำงานเป็นอย่างไร เพื่อความเข้าใจและเป้นปัญญาทานครับ ขอบพระคุฯเป็นอย่างสูง
3 @R19622
@แหลมทอง ผมเป็น User ทั่วไปเหมือนคุณครับ ไม่ได้เป็นอาจารย์อะไร คงตอบแบบเชิงการสอนคงไม่ได้ดี ผมได้แค่แนะนำแล้วให้ไปศึกษาต่อเองนะครับ
ที่เห็นคือการใช้ คิวรี่ย่อย (Subqueries) ให้มองเป็นกลุ่มของ (Select...) ที่อยู่ภายในวงเล็บ ก็เหมือนเราทำคิวรี่อีกคิวรี่มาใช้เพื่อเปรียบเทียบกับอีกคิวรี่ เช่นกรณีนี้คือการสร้างคิวรี่จากตาราง Table1 ตารางเดียวกัน ทำเป็น 2 คิวรี่ คือ a กับ b เพื่อให้โปรแกรมเทียบค่าฟิลด์ ID ตามเงื่อนไขที่ต้องการอีกทีครับ ลองศึกษาเรื่อง คิวรี่ย่อย (Subqueries) ดูครับ
ที่เห็นคือการใช้ คิวรี่ย่อย (Subqueries) ให้มองเป็นกลุ่มของ (Select...) ที่อยู่ภายในวงเล็บ ก็เหมือนเราทำคิวรี่อีกคิวรี่มาใช้เพื่อเปรียบเทียบกับอีกคิวรี่ เช่นกรณีนี้คือการสร้างคิวรี่จากตาราง Table1 ตารางเดียวกัน ทำเป็น 2 คิวรี่ คือ a กับ b เพื่อให้โปรแกรมเทียบค่าฟิลด์ ID ตามเงื่อนไขที่ต้องการอีกทีครับ ลองศึกษาเรื่อง คิวรี่ย่อย (Subqueries) ดูครับ
4 @R19624
คุณแหลมทอง ช่วย Print Screen หน้า Query ในมุมมองออกแบบ ให้ดูหน่อยครับ มองภาพ Sub Query ไม่ออก ขอบคุณมากครับ
5 @R19625
ตามนี้ครับ...
ผมมีข้อมูลทั้งปี แสนกว่า Record ประมวลผลนานมากครับ (ต้องก้ปัญหาด้วยการตัดทีละเดือน) เนื่องจากต้องนำข้อมูลทั้งหมด มาหาค่าเฉลี่ย ต่อครั้งของการรับบริการ และระยะเวลารอคอย
ผมมีข้อมูลทั้งปี แสนกว่า Record ประมวลผลนานมากครับ (ต้องก้ปัญหาด้วยการตัดทีละเดือน) เนื่องจากต้องนำข้อมูลทั้งหมด มาหาค่าเฉลี่ย ต่อครั้งของการรับบริการ และระยะเวลารอคอย
6 @R19627
SELECT a.HN, a.VSTDATE, a.ID, a.CLINIC, a.REG, a.DCH, IIf(IsNull((SELECT Min([REG]) FROM Table1 AS b WHERE a.ID < b.ID And a.VSTDATE=b.VSTDATE And a.hn=b.hn )),[REG],(SELECT Min([REG]) FROM Table1 AS b WHERE a.ID < b.ID And a.VSTDATE=b.VSTDATE And a.hn=b.hn)) AS BF_DCH_TIME
FROM Table1 AS a
ORDER BY a.HN, a.VSTDATE, a.ID;
จากตัวอย่าง คือจริงๆเราสามารถการคิวรี่ซ้ำสองครั้งได้ โดยสร้างฟิลด์ใหม่ เช่น
TTT: (SELECT Min([REG]) FROM Table1 AS b WHERE a.ID < b.ID And a.VSTDATE=b.VSTDATE And a.hn=b.hn )
แล้วค่อยนำฟิลด์นี้มาใช้อีกครั้ง
SELECT a.HN, a.VSTDATE, a.ID, a.CLINIC, a.REG, a.DCH, IIf(IsNull([TTT]),[REG],[TTT]) AS BF_DCH_TIME
FROM Table1 AS a
ORDER BY a.HN, a.VSTDATE, a.ID;
น่าจะช่วยลดการคิวรี่ได้รอบนึง ทำให้เร็วขึ้นอีกหน่อย แต่อย่างไรก็ตามวิธีนี้ก็ไม่เหมาะกับเรคคอร์ดระดับแสนอยู่แล้วครับ
FROM Table1 AS a
ORDER BY a.HN, a.VSTDATE, a.ID;
จากตัวอย่าง คือจริงๆเราสามารถการคิวรี่ซ้ำสองครั้งได้ โดยสร้างฟิลด์ใหม่ เช่น
TTT: (SELECT Min([REG]) FROM Table1 AS b WHERE a.ID < b.ID And a.VSTDATE=b.VSTDATE And a.hn=b.hn )
แล้วค่อยนำฟิลด์นี้มาใช้อีกครั้ง
SELECT a.HN, a.VSTDATE, a.ID, a.CLINIC, a.REG, a.DCH, IIf(IsNull([TTT]),[REG],[TTT]) AS BF_DCH_TIME
FROM Table1 AS a
ORDER BY a.HN, a.VSTDATE, a.ID;
น่าจะช่วยลดการคิวรี่ได้รอบนึง ทำให้เร็วขึ้นอีกหน่อย แต่อย่างไรก็ตามวิธีนี้ก็ไม่เหมาะกับเรคคอร์ดระดับแสนอยู่แล้วครับ
7 @R19638
เห็นด้วยอย่างยิ่งครับ ไม่เหมาะกับเรคคอร์ดระดับแสน ผมแก้ปัญหา ด้วยการ Export เป็น ตระกูล .DBF แล้ว ใช้ Query ที่คุณ TTT ให้มา Run ด้วย Foxpro ก็ใช้เวลา ไม่ถึง 3 นาที (ระดับ 1.6 แสน Rec.) ก้พอแก้ปัญหาไปได้ระดับหนึ่ง
ข้อสังเกตุ ตรงฟังชั่นก์ Min หรือ Max ผมลองเปลี่ยนมาใช้ค่า First หรือ Last มีข้อแตกต่าง กันครับ แต่ผมไม่รู้จะอธิบายยังไง....
(SELECT Min([DCH]) FROM Table1 AS b WHERE a.ID < b.ID And a.VSTDATE=b.VSTDATE And a.hn=b.hn )
กับ
(SELECT First([DCH]) FROM Table1 AS b WHERE a.ID < b.ID And a.VSTDATE=b.VSTDATE And a.hn=b.hn )
ให้ผลไม่เหมือนกัน
ขอบคุณ....คุณ TTT มากครับ
ข้อสังเกตุ ตรงฟังชั่นก์ Min หรือ Max ผมลองเปลี่ยนมาใช้ค่า First หรือ Last มีข้อแตกต่าง กันครับ แต่ผมไม่รู้จะอธิบายยังไง....
(SELECT Min([DCH]) FROM Table1 AS b WHERE a.ID < b.ID And a.VSTDATE=b.VSTDATE And a.hn=b.hn )
กับ
(SELECT First([DCH]) FROM Table1 AS b WHERE a.ID < b.ID And a.VSTDATE=b.VSTDATE And a.hn=b.hn )
ให้ผลไม่เหมือนกัน
ขอบคุณ....คุณ TTT มากครับ
8 @R19640
ขอแนะนำนะครับ
- ถ้า Visit Date มีการใส่เวลา ชม. นาที วินาทีไปด้วย ก็ไม่จำเป็นต้องมี ID นะครับ ใช้ Visit Date เรียงลำดับแทน ID ได้เลย
- ให้สร้าง index ของ table1 ด้วย 4 ฟิลด์คือ HN, Visit Date, ID, REG จะทำให้คิวรี่นี้ทำงานได้เร็วขึ้นมาก
- สามารถไม่เขียน sub query ซ้ำได้ โดยครอบ sub query เดิมอีกชั้นนึง
SELECT a.HN, .... , IIf(IsNull(a.TTT),REG,a.TTT) AS BF_DCH_TIME
FROM
(
SELECT b.HN, b.VSTDATE, b.ID, b.CLINIC, b.REG, b.DCH
, (SELECT Min(c.REG)
FROM Table1 AS c
WHERE c.ID > b.ID And c.VSTDATE=b.VSTDATE And c.hn=b.hn) as TTT
FROM Table1 AS b
) AS a
ORDER BY a.HN, a.VSTDATE, a.ID;
- ถ้า Visit Date มีการใส่เวลา ชม. นาที วินาทีไปด้วย ก็ไม่จำเป็นต้องมี ID นะครับ ใช้ Visit Date เรียงลำดับแทน ID ได้เลย
- ให้สร้าง index ของ table1 ด้วย 4 ฟิลด์คือ HN, Visit Date, ID, REG จะทำให้คิวรี่นี้ทำงานได้เร็วขึ้นมาก
- สามารถไม่เขียน sub query ซ้ำได้ โดยครอบ sub query เดิมอีกชั้นนึง
SELECT a.HN, .... , IIf(IsNull(a.TTT),REG,a.TTT) AS BF_DCH_TIME
FROM
(
SELECT b.HN, b.VSTDATE, b.ID, b.CLINIC, b.REG, b.DCH
, (SELECT Min(c.REG)
FROM Table1 AS c
WHERE c.ID > b.ID And c.VSTDATE=b.VSTDATE And c.hn=b.hn) as TTT
FROM Table1 AS b
) AS a
ORDER BY a.HN, a.VSTDATE, a.ID;
Time: 0.3462s
HN VSTDATE CLINIC REG DCH
... .... ... ... ...
ให้เพิ่มฟิลด์ ชื่อ ID โดยกำหนดเป็น AutoNumber(หมายถึงเลขลำดับที่เลขไม่ซ้ำกัน)
ID HN VSTDATE CLINIC REG DCH
... ... .... ... ... ...
จากนั้นเขียน SQL ดังนี้ครับ โดยสมมุติตารางชื่อ Table1
SELECT a.HN, a.VSTDATE, a.CLINIC, a.REG, a.DCH, IIf(IsNull((SELECT min([REG]) FROM Table1 AS b WHERE a.ID < b.ID)),[REG],(SELECT min([REG]) FROM Table1 AS b WHERE a.ID < b.ID)) AS BF_DCH_TIME
FROM Table1 AS a;
ปรับใช้ดูครับ