กระทู้เก่าบอร์ด อ.Yeadram
8,748 28
URL.หัวข้อ /
URL
การใช้ Group By
คือผมเขียนคิวรี่โดยใช้คำสั่ง group by
select proid,qty,Sum(amount) as sumamount
from inv_stockcarddetail
group by proid ;
ประมาณนี้นะครับ ผมสงสัยว่าทำไม โปรแกรมมันถึงฟ้อง error ตรง qty ว่า you tried to execute a query that does not include the specified expression 'qty' as part of an aggregate function.
แต่ถ้าใส่ sum เข้าไปกลับไม่มีปัญหา หรือว่าต้องใส่อะไรยังไงครับ
select proid,qty,Sum(amount) as sumamount
from inv_stockcarddetail
group by proid ;
ประมาณนี้นะครับ ผมสงสัยว่าทำไม โปรแกรมมันถึงฟ้อง error ตรง qty ว่า you tried to execute a query that does not include the specified expression 'qty' as part of an aggregate function.
แต่ถ้าใส่ sum เข้าไปกลับไม่มีปัญหา หรือว่าต้องใส่อะไรยังไงครับ
28 Reply in this Topic. Dispaly 2 pages and you are on page number 1
2 @R03754
เมื่อคุณใช้ group by นั่นหมายถึง คุณต้องการหาผลลัพธ์จากการรวมกลุ่ม ซึ่งผลของมันย่อมเป็นไปได้แค่ 2 ประเภทเท่านั้น คือ ดัวฟิลด์ที่ใช้ในการรวมกลุ่มเอง หรือ ฟังก์ชั่นที่เป็นผลจากการรวมกลุ่มที่เรียกกันว่า Aggregate Function เช่น ผลรวมตามกลุ่ม (Sum()), ค่าสูงสุดตามกกลุ่ม (Max()), ค่าต่ำสุดตามกลุ่ม (Min()) เป็นต้น
ดังนั้น ฟิลด์ qty ไม่ได้เป็นทั้งฟิลด์ที่เป็นเงื่อนไขในการรวมกลุ่ม และไม่ได้เป็นทั้งผลจากฟังก์ชั่นตามที่บอกไปแล้ว มันจึงไม่รู้จะเอาค่าอะไรของ qty มาแสดงให้ได้ ก็เท่านั้นเองครับ
ดังนั้น ฟิลด์ qty ไม่ได้เป็นทั้งฟิลด์ที่เป็นเงื่อนไขในการรวมกลุ่ม และไม่ได้เป็นทั้งผลจากฟังก์ชั่นตามที่บอกไปแล้ว มันจึงไม่รู้จะเอาค่าอะไรของ qty มาแสดงให้ได้ ก็เท่านั้นเองครับ
3 @R03755
สมมุติฟิลด์ชื่อ f_no, f_in, f_out จากเทเบิลชื่อ f
SQL Statement ที่ใช้หาผลลัพธ์ตามที่ต้องการคือ
SELECT f1.f_no, f1.f_in, f1.f_out, (select sum(f2.f_in - f2.f_out) from f as f2 where f2.f_no <= f1.f_no) AS balance
FROM f AS f1
ORDER BY f1.f_no, No
SQL Statement ที่ใช้หาผลลัพธ์ตามที่ต้องการคือ
SELECT f1.f_no, f1.f_in, f1.f_out, (select sum(f2.f_in - f2.f_out) from f as f2 where f2.f_no <= f1.f_no) AS balance
FROM f AS f1
ORDER BY f1.f_no, No
4 @R03758
เรื่องที่ 1. Group by
ถ้าผมต้องการให้แสดง qty ด้วย อย่างนี้ผมต้องทำอย่างไรครับ
ถ้าผมต้องการให้แสดง qty ด้วย อย่างนี้ผมต้องทำอย่างไรครับ
5 @R03760
ก็ต้องถามตัวเองว่า qty นั้นเป็นผลของการรวมกลุ่มหรือไม่ ถ้าเป็น เป็นผลมาจาก Aggregate Function ไหน หรือว่าเราจะรวมกลุ่มตาม prodid และ qty ด้วย หมายถึงสินค้าเดียวกัน และจำนวนขายเท่ากัน ก็รวมเป็นกล่มนึง
เมื่อถามตัวเองได้คำตอบแล้ว คุณก็จะตอบคำถามตัวเองได้โดยปริยาย
เมื่อถามตัวเองได้คำตอบแล้ว คุณก็จะตอบคำถามตัวเองได้โดยปริยาย
6 @R03817
เอ่อ อาจารย์ครับ ผมขอถามเรื่องฐานข้อมูลหน่อยครับ
คือฟิลด์ no ตอนแรกผมตั้งเป็น text ไว้ แต่ทีนี้ตามโค๊ตนี้มันต้องมีการรันเลขที่ไปเรื่อยๆเพื่อเช็คค่าก่อนหลัง ผมเลยไปแก้ที่ mysql ให้ฟิลด์ no เป็น auto increment
แต่ไม่รู้ทำไมมันไม่ยอมให้สร้างครับ error ตลอด ผลลองสร้าง table ใหม่เลยแล้วลองตั้ง auto increment มันก็ไม่ได้อยู่ดีครับ
Error
SQL query:
ALTER TABLE `inv_stockcarddetail` CHANGE `no` `no` INT( 11 ) NOT NULL AUTO_INCREMENT
MySQL said: Documentation
#1075 - Incorrect table definition; there can be only one auto column and it must be defined as a key
คือฟิลด์ no ตอนแรกผมตั้งเป็น text ไว้ แต่ทีนี้ตามโค๊ตนี้มันต้องมีการรันเลขที่ไปเรื่อยๆเพื่อเช็คค่าก่อนหลัง ผมเลยไปแก้ที่ mysql ให้ฟิลด์ no เป็น auto increment
แต่ไม่รู้ทำไมมันไม่ยอมให้สร้างครับ error ตลอด ผลลองสร้าง table ใหม่เลยแล้วลองตั้ง auto increment มันก็ไม่ได้อยู่ดีครับ
Error
SQL query:
ALTER TABLE `inv_stockcarddetail` CHANGE `no` `no` INT( 11 ) NOT NULL AUTO_INCREMENT
MySQL said: Documentation
#1075 - Incorrect table definition; there can be only one auto column and it must be defined as a key
7 @R03820
อีกอย่างนึงครับผมลองเทสรายงานยอดคงเหลือดู
ตอนแรกไม่มีปัญหาอะไรครับ แต่พอรันอีกครั้ง เปลี่ยนช่วงวันที่ มันกลับดึงเลขจากไหนมาคำนวณก็ไม่ทราบครับ
โดยคิวรี่ที่ผมเขียนจะดึงข้อมูลมาจากช่วงวันที่ที่เลือกครับ แล้วใช้ no ตรวจสอบอันไหนมาก่อนหลังครับ
ตอนแรกไม่มีปัญหาอะไรครับ แต่พอรันอีกครั้ง เปลี่ยนช่วงวันที่ มันกลับดึงเลขจากไหนมาคำนวณก็ไม่ทราบครับ
โดยคิวรี่ที่ผมเขียนจะดึงข้อมูลมาจากช่วงวันที่ที่เลือกครับ แล้วใช้ no ตรวจสอบอันไหนมาก่อนหลังครับ
8 @R03821
- ผมไม่ชำนาญการใช้คำสั่งพวก DDL ครับ ก็ไม่รู้ว่าคำสั่ง ALTER TABLE นั้นถูกต้องหรือไม่ พอไปค้นใน Google ก็เห็นมีบางคนแนะนำคำสั่งนี้
- อีกปัญหาก็คงเกี่ยวกับช่วงวันที่แหล่ะครับ ผมก็ไม่เคยเรียกใช้ผ่าน ODBC ด้วยเช่นกัน ปัญหาที่ว่า ผมหมายถึง เราจะต้องส่งวันที่ในรูปแบบอะไรไปให้ ODBC ดี และใช้สัญญลักษณ์อะไรเป็น delimited เช่น ข้อกำหนดของ ODBC ต้องส่งเป็น #เดือน/วัน/ปี# เท่านั้นหรือไม่ ตรงนี้ต้องลองไปอ่าน Help ของ ODBC ดูครับ
ถ้าใครพอทราบก็ช่วยตอบด้วยครับ
alter table ชื่อเทเบิล add ชื่อพิลด์ int(11) primary key auto_increment not null
- อีกปัญหาก็คงเกี่ยวกับช่วงวันที่แหล่ะครับ ผมก็ไม่เคยเรียกใช้ผ่าน ODBC ด้วยเช่นกัน ปัญหาที่ว่า ผมหมายถึง เราจะต้องส่งวันที่ในรูปแบบอะไรไปให้ ODBC ดี และใช้สัญญลักษณ์อะไรเป็น delimited เช่น ข้อกำหนดของ ODBC ต้องส่งเป็น #เดือน/วัน/ปี# เท่านั้นหรือไม่ ตรงนี้ต้องลองไปอ่าน Help ของ ODBC ดูครับ
ถ้าใครพอทราบก็ช่วยตอบด้วยครับ
9 @R03822
ลองเอา คิวรี่ ที่ดึงข้อมูลมาแสดงให้ดูหน่อย
10 @R03824
SELECT f1.invoiceid, f1.invoicedate, inv_products.name, inv_products.description, inv_products.unit, f1.quantity, f1.number, f1.moneyin, f1.moneyout, (select sum(f2.moneyin - f2.moneyout) from inv_StockCardDetail as f2 where f2.number <= f1.number ) AS balance, f1.comment
FROM inv_StockCardDetail AS f1 INNER JOIN inv_products ON f1.proid = inv_products.name
WHERE (((f1.invoicedate)>=[Forms]![CC-Sales Reports Dialog]![FromDate] And (f1.invoicedate)<=[Forms]![CC-Sales Reports Dialog]![ToDate]))
ORDER BY f1.number;
FROM inv_StockCardDetail AS f1 INNER JOIN inv_products ON f1.proid = inv_products.name
WHERE (((f1.invoicedate)>=[Forms]![CC-Sales Reports Dialog]![FromDate] And (f1.invoicedate)<=[Forms]![CC-Sales Reports Dialog]![ToDate]))
ORDER BY f1.number;
11 @R03825
ผมเชื่อว่า
WHERE (((f1.invoicedate)>=[Forms]![CC-Sales Reports Dialog]![FromDate] And (f1.invoicedate)<=[Forms]![CC-Sales Reports Dialog]![ToDate]))
นี่แหล่ะคือตัวปัญหา เพราะ FromDate และ ToDate ยังไงมันก็คือ Textbox ค่าที่ได้ก็คือ Text ไม่ใช่ข้อมูลประเภท Date มันต้องเกิดการแปลงให้เองอย่างอัตโนมัติ ซึ่งอาจจะแปลงถูกแปลงผิดก็ได้ เช่นถ้า FromDate บนหน้าจอเป็นค่า 1/10/2009 ถามหน่อยว่า มันจะรู้ได้อย่างไรว่าเป็น เดือน 10 หรือ เดือน 1 กันแน่ ทางที่ดีที่สุด ถ้าเรารู้ว่าข้อกำหนดในการเขียนเพื่อส่งไป ODBC นั้น เป็นรูปแบบไหน เราก็เขียนรูปแบบนั้นตรงๆไปเลยจะดีกว่าครับ
WHERE (((f1.invoicedate)>=[Forms]![CC-Sales Reports Dialog]![FromDate] And (f1.invoicedate)<=[Forms]![CC-Sales Reports Dialog]![ToDate]))
นี่แหล่ะคือตัวปัญหา เพราะ FromDate และ ToDate ยังไงมันก็คือ Textbox ค่าที่ได้ก็คือ Text ไม่ใช่ข้อมูลประเภท Date มันต้องเกิดการแปลงให้เองอย่างอัตโนมัติ ซึ่งอาจจะแปลงถูกแปลงผิดก็ได้ เช่นถ้า FromDate บนหน้าจอเป็นค่า 1/10/2009 ถามหน่อยว่า มันจะรู้ได้อย่างไรว่าเป็น เดือน 10 หรือ เดือน 1 กันแน่ ทางที่ดีที่สุด ถ้าเรารู้ว่าข้อกำหนดในการเขียนเพื่อส่งไป ODBC นั้น เป็นรูปแบบไหน เราก็เขียนรูปแบบนั้นตรงๆไปเลยจะดีกว่าครับ
12 @R03833
คือเรื่อง odbc นี่ผมก็ไม่ค่อยเข้าใจอะครับ
เพราะผมมาทำต่ออีกทีครับ คือผมเพิ่มมาใช้ access งานแรกเลยครับ
แล้วทีนี้ผมต้องแก้ปัญหายังไงครับ
เพราะผมมาทำต่ออีกทีครับ คือผมเพิ่มมาใช้ access งานแรกเลยครับ
แล้วทีนี้ผมต้องแก้ปัญหายังไงครับ
13 @R03834
MySQL ต้องส่งค่าวันที่ เข้าไปในรูปแบบ yyyy-mm-dd และส่วนใหญ่ พวกฐานข้อมูลระดับใหญ่มักจะใช้แบบนี้กันทั้งนั้น
ถ้าปัญหามันเป็นอย่างที่ อ.สันติสุขว่า คุณก็น่าจะปรับรูปแบบของ วันที่ให้อยู่ในรูปแบบที่ MySQL ยอมรับได้ซะก่อน ก่อนจะส่ง statement เข้าไป
dim fDate as string
dim tDate as string
fDate = format([Forms]![CC-Sales Reports Dialog]![FromDate],"yyyy-mm-dd")
tDate = format(Forms]![CC-Sales Reports Dialog]![ToDate], "yyyy-mm-dd")
- เขียน statement ตามปกติ เมือถึง where ก็ใช้
WHERE (f1.invoicedate Between '" & fDate & "' AND '" & tDate & "')"
ถ้าปัญหามันเป็นอย่างที่ อ.สันติสุขว่า คุณก็น่าจะปรับรูปแบบของ วันที่ให้อยู่ในรูปแบบที่ MySQL ยอมรับได้ซะก่อน ก่อนจะส่ง statement เข้าไป
dim fDate as string
dim tDate as string
fDate = format([Forms]![CC-Sales Reports Dialog]![FromDate],"yyyy-mm-dd")
tDate = format(Forms]![CC-Sales Reports Dialog]![ToDate], "yyyy-mm-dd")
- เขียน statement ตามปกติ เมือถึง where ก็ใช้
WHERE (f1.invoicedate Between '" & fDate & "' AND '" & tDate & "')"
14 @R03835
ลองแบบที่เรียกใช้กับฐานข้อมูลของ Access เองดูก่อนครับ อาจเหมือนกัน
ก่อนอื่นเนื่องจากเพราะการตีความของวันที่ที่มันไม่แน่ใจนั้น มันจะใช้รูปแบบที่กำหนดใน Control Panel ดังนั้นไปที่ Control Panel > Regional and Language Options > Regional > Options > Customize > Date > Short Date Format ให้เป็น dd/mm/yyyy ต่อมาในเท็กซ์บ๊อกส์ที่รับค่าวันที่ ไม่ต้องกำหนด InputMask แต่กำหนด Format ให้เป็น Short Date ดังนั้นไม่ว่าคุณจะป้อนเป็น 1/10/2009 หรือ 1-10-2009 หรือ 1-oct-2009 หรือ 1 oct 2009 หรือ 1/11/9 มันก็จะพยายามแปลงให้เห็นเป็น 1/11/2009 ตาม Short Date Format ที่เราได้กำหนดไว้ก่อนหน้านี้ และเราก็จะมั่นใจได้ว่ามันคือวันที่ 1 ตุลาคม 2009 ไม่ใช่เป็นวันที่ 10 มกราคม 2009
เข้าใจว่าคุณสร้างเป็น Query object ใช่ไหม ไม่ใช่เป็นคำสั่ง SQL Statement ใน VBA ดังนั้นก็ลองสั่งให้ทำงานได้เลย
ถ้ายังไม่ได้ยังไงก็มาคุยกันอีกที
ก่อนอื่นเนื่องจากเพราะการตีความของวันที่ที่มันไม่แน่ใจนั้น มันจะใช้รูปแบบที่กำหนดใน Control Panel ดังนั้นไปที่ Control Panel > Regional and Language Options > Regional > Options > Customize > Date > Short Date Format ให้เป็น dd/mm/yyyy ต่อมาในเท็กซ์บ๊อกส์ที่รับค่าวันที่ ไม่ต้องกำหนด InputMask แต่กำหนด Format ให้เป็น Short Date ดังนั้นไม่ว่าคุณจะป้อนเป็น 1/10/2009 หรือ 1-10-2009 หรือ 1-oct-2009 หรือ 1 oct 2009 หรือ 1/11/9 มันก็จะพยายามแปลงให้เห็นเป็น 1/11/2009 ตาม Short Date Format ที่เราได้กำหนดไว้ก่อนหน้านี้ และเราก็จะมั่นใจได้ว่ามันคือวันที่ 1 ตุลาคม 2009 ไม่ใช่เป็นวันที่ 10 มกราคม 2009
เข้าใจว่าคุณสร้างเป็น Query object ใช่ไหม ไม่ใช่เป็นคำสั่ง SQL Statement ใน VBA ดังนั้นก็ลองสั่งให้ทำงานได้เลย
ถ้ายังไม่ได้ยังไงก็มาคุยกันอีกที
15 @R03851
อาจารย์ครับ
พอรันครั้งแรก ก็ไม่มีปัญหาอะไรครับคำนวณถูกต้อง แต่พอเปลี่ยนวันที่ ก็ผิดพลาดเลยครับ คือผมเดาว่า เหมือนกับมันจำจำนวนเก่าไว้แล้วเอามาบวกอีกทีนึงนะครับ
พอรันครั้งแรก ก็ไม่มีปัญหาอะไรครับคำนวณถูกต้อง แต่พอเปลี่ยนวันที่ ก็ผิดพลาดเลยครับ คือผมเดาว่า เหมือนกับมันจำจำนวนเก่าไว้แล้วเอามาบวกอีกทีนึงนะครับ
16 @R03853
แล้วก็ผมขอถามหน่อยครับว่า
(select sum(f2.moneyin - f2.moneyout) from inv_StockCardDetail as f2 where f2.number <= f1.number ) AS balance
ตรง where f2.number แล้ว f2.number นี่แทนค่าอะไรหรอครับ
(select sum(f2.moneyin - f2.moneyout) from inv_StockCardDetail as f2 where f2.number <= f1.number ) AS balance
ตรง where f2.number แล้ว f2.number นี่แทนค่าอะไรหรอครับ
17 @R03854
select sum(f2.moneyin - f2.moneyout)
เลือก ผลรวมของผลต่างจากมูลค่าเข้าและออก
from inv_StockCardDetail as f2
จากเทเบิล inv_StockCardDetail โดยใช้ชื่อเล่นว่า f2
where f2.number <= f1.number
โดยเลือกเฉพาะเรคอร์ดที่ฟิลด์ number จาก f2 นี้ มีค่าน้อยกว่าฟิลด์เดียวกันที่กำลังจะแสดงผลในแต่ละบบรรทัด ซึ่งคือ f1.number นั่นเอง
เลือก ผลรวมของผลต่างจากมูลค่าเข้าและออก
from inv_StockCardDetail as f2
จากเทเบิล inv_StockCardDetail โดยใช้ชื่อเล่นว่า f2
where f2.number <= f1.number
โดยเลือกเฉพาะเรคอร์ดที่ฟิลด์ number จาก f2 นี้ มีค่าน้อยกว่าฟิลด์เดียวกันที่กำลังจะแสดงผลในแต่ละบบรรทัด ซึ่งคือ f1.number นั่นเอง
18 @R03856
แล้วอาจารย์พอจะทราบมั้ยครับว่าทำไมพอรันครั้งแรก ก็ไม่มีปัญหาอะไรครับคำนวณถูกต้อง แต่พอเปลี่ยนวันที่ ก็ผิดพลาดเลยครับ คือผมเดาว่า เหมือนกับมันจำจำนวนเก่าไว้แล้วเอามาบวกอีกทีนึงนะครับ
ผมมีแนวคิดว่าจะเปลี่ยนมาเขียน vba แต่ก็ไม่เก่งอีก
ผมมีแนวคิดว่าจะเปลี่ยนมาเขียน vba แต่ก็ไม่เก่งอีก
19 @R03857
- ช่วงวันที่ในการรันครั้งแรกคือค่าอะไร และครั้งที่สองคือค่าอะไร
- ฟิลด์ invoicedate ในเทเบิล มี data type เป็นอะไร
- ฟิลด์ invoicedate ในเทเบิล มี data type เป็นอะไร
20 @R03858
- ช่วงวันที่ในการรันครั้งแรกคือค่าอะไร และครั้งที่สองคือค่าอะไร
------ ครั้งแรก 12/10/2552 - 12/10/2552
------ ครั้งที่สอง 13/10/2552 - 13/10/2552
ทีนี้พอผมกลับไปเลือกเป็นวันที่ 12/10/2552 - 12/10/2552 ก็ไม่ได้อยู่ดีครับ
- ฟิลด์ invoicedate ในเทเบิล มี data type เป็นอะไร
------ date
------ ครั้งแรก 12/10/2552 - 12/10/2552
------ ครั้งที่สอง 13/10/2552 - 13/10/2552
ทีนี้พอผมกลับไปเลือกเป็นวันที่ 12/10/2552 - 12/10/2552 ก็ไม่ได้อยู่ดีครับ
- ฟิลด์ invoicedate ในเทเบิล มี data type เป็นอะไร
------ date
Time: 0.2783s
no เงินเข้า เงินออก ยอดคงเหลือ
1 200 - 200
2 500 - 700
3 - 300 400
4 100 - 500
5 - 500 0