 |
|
หาค่า max ค่ะ SELECT a.CustomerCode as Customer,b.Itemcode as Item, sum(b.qtyorder) AS total_qty FROM |
|
 |
|
|
 |
 |
|
SELECT a.CustomerCode as Customer,b.Itemcode as Item, sum(b.qtyorder) AS total_qty FROM SO a INNER JOIN
SO_Detail b ON a.SOID = b.SOID
group by a.CustomerCode,b.Itemcode
///// อันนี้คือหาค่า sum จำนวนที่สั่งซื้อค่ะ
ผลลัพธ์จะได้แบบนี้ค่ะ
customer : Itemcode : total_qty
001 : 1 : 10
002 : 1 : 12
003 : 1 : 15
001 : 2 : 20
003 : 2 : 15
-------------------------------
แล้วทีนี้ต้องการดึงข้อมูลที่มีค่ามากสุดของแต่ละ item ออกมาค่ะ จะต้องได้แบบนี้ค่ะ
003 : 1 : 15
001 : 2 : 20
และต้อง นับจำนวนของแต่ละ item ว่ามี customer กี่คน ผลลัพธ์สุดท้ายก็จะได้
cusmain : itemcode : total_qty : total_cus
003 : 1 : 15 : 3
001 : 2 : 20 : 2
---------------------------------
เลยเขียนแบบนี้ไว้ค่ะ
select max(total_qty) as CusMain,customer,item,count(total_qty) as total_cus
from (SELECT a.CustomerCode as customer,b.itemcode as item, sum(b.qtyorder) AS total_amt
FROM SO a INNER JOIN
SO_Detail b ON a.SOID = b.SOID
group by a.CustomerCode,b.itemcode) SUMCusMain
group by customer,item
แต่ว่ามันผิดค่ะ มันเล่นเอาข้อมูลออกมาอย่างละเรคคอร์ด ไม่ได้ดึงค่า max ออกมาค่ะ เพราะว่ามันติด group by
แต่พอไม่ใส่ group by มันก็ error ว่า
Column 'SUMCusMain.customer' is invalid in the select list because it is not contained in an aggregate function and there is no GROUP BY clause.
ช่วยด้วยค่ะ
Tag : - - - -
|
|
 |
 |
 |
 |
Date :
2010-03-03 18:02:16 |
By :
Angel_baba |
View :
1603 |
Reply :
11 |
|
 |
 |
 |
 |
|
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
เนื่องจากไม่มีตารางของคุณ เลยจำลอง
SELECT a.CustomerCode as Customer,b.Itemcode as Item, sum(b.qtyorder) AS total_qty FROM SO a INNER JOIN
SO_Detail b ON a.SOID = b.SOID
group by a.CustomerCode,b.Itemcode
ทั้งก้อนเปนตารางนึงแล้วจัดเก็บไว้ใน View ของ MSSQL
ซึ่งแนะนะให้คุณเอาทั้งก้อน นี้ไปเก็บไว้ใน VIEW ด้วยเช่นกันค่ะ
เพื่อลดความซับซ้อนในการสร้าง QUERY ต่อไป
จากนั้นก็ Solved หาวิธี ซึ่งก้อทำจนออกมาเป็นผลลัพธ์ที่คุณต้องการได้นะคะ
แต่ ใน Query ของคุณมีข้อขัดแย้งอยู่ซึ่ง เนื่องจากว่าไม่ใช่คนออกแบบ
จึงไม่อาจคาดเดาไปมากกว่านี้ เดี๋ยวจะชี้ให้ดูค่ะว่าขัดแย้งกันอย่างไร
อาจะยาวนะคะ

ซึ่งดูเหมือนจะทำได้ตามที่ต้องการ แต่เราลองมาแปลความหมายกันค่ะ
มันคือ ข้อมูลนี้คือ ข้อมูล item_code ที่มีจำนวนมากที่สุด ซึ่ง item นี้มีลูกค้าอยู่ n จำนวนโดยที่
ณ รายการที่มีจำนวนมากที่สุดโดย ลูกค้า.... << Cusmain
ตัวที่ขัดแย้งเลยคือ Custmain ซึ่งไม่ทราบเอาไปใช้ทำอะไร ซึ่งถ้าเกิดมี Customer
มียอดซื้อ item นี้เป็นจำนวนสูงสุดเท่่าๆกัน ซึ่งเป็นไปได้หรือเปล่าไม่ทราบนะคะ แต่ถ้ามีล่ะ
ก็จะได้ผลลัพธ์แบบนี้

แต่ถ้าคุณตัดเจ้า Custmain นี้ออกไป จะเขียนได้สั้นขึ้นกระชับขี้น
และถูกต้องไม่ว่าจะมีกรณีข้างต้น ดังนี้ค่ะ

ไม่ทราบว่าตีความผิดหรือเปล่านะคะ ขอบคุณมากค่ะ
|
 |
 |
 |
 |
Date :
2010-03-03 19:33:58 |
By :
blurEye |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
เข้าใจถูกแล้วค่ะ แต่ว่า ไม่สามารถตัด cusmain ออกไปได้ค่ะ เพราะสิ่งที่ต้องการมากที่สุด ก็คือรหัสลูกค้าที่ ซื้อสินค้าเยอะที่สุดตามรหัสนั้นๆ
ซึ่งถ้าเกิดกรณีที่มีลูกค้ามากกว่า 1 คน ที่ซื้อสินค้าสูงสุดเท่ากัน ดังที่คุณ blurEye บอกมา นั่นเป็นปัญหาที่ไม่ได้คิดไว้เลยค่ะ ลืมไปได้ไงไม่ทราบ!
แล้วถ้าในกรณีนี้พอทราบบ้างมั้ยคะ ว่าควรแก้ไขอย่างไรถึงจะดี
ขอบคุณมากๆค่ะ
|
 |
 |
 |
 |
Date :
2010-03-03 21:01:47 |
By :
Angel_baba |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
คือเนื่องจากตัวข้อมูลเป็นแบบนี้ Query รายงานออกแบบนั้น
ที่อาจจะผิดคือ ผลรวมของลูกค้าทั้งหมดค่ะ และผลรวมของ ยอดสินค้า
เพราะถ้าคิดจาก Query ที่ออกมาจะเกินไปจากความจริงค่ะ
นอกนั้น น่าจะรับได้นะคะ
อีกอย่างลูกค้าซื้อของเท่ากันก้อควรจะรายงานออกมา
เพียงแต่ว่าตอนรายงานผลงรวมยอดลูกค้าทั้งหมด ใหัไป COUNT จาก Query อื่นแทน
และเพิ่ม column comment อีกช่อง แล้วใส่ดอกจันหรืออื่นใดเพื่อบอกว่า
ข้อมูลซ้ำให้หักจำนวนคนกำหักจำนวนสินค้าออกค่ะ
จะลองเขียน protect อีกชั้นนะคะ พยายามจะไม่ให้ซับซ้อนมากค่ะ ^^
|
 |
 |
 |
 |
Date :
2010-03-03 21:39:06 |
By :
blurEye |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|

ใช้ TRICK ตอนสร้าง VIEW จะจัดรูปแบบให้ง่ายก่อนเข้าค่ะ
โดยการสร้าง dynamic id เอาไว้ซึ่งมีค่าเป็นตัวเลข
แล้วหาค่า MIN() ซึ่งหมายถึงลูกค้าคนแรกในกลุ่มนั้นค่ะ
Code (C#)
// ****************** ใน View ******************
SELECT QR_FIRST.*
,row_number()
OVER (ORDER BY QR_FIRST.Item_code
,QR_FIRST.total ,QR_FIRST.customer_code) AS dynamic_id
FROM
(
SELECT a.CustomerCode as customer_code
,b.Itemcode as Item_code, sum(b.qtyorder) AS total
FROM SO a INNER JOIN SO_Detail b
ON a.SOID = b.SOID
GROUP BY b.Itemcode ,a.CustomerCode
) AS QR_FIRST
ORDER BY QR_FIRST.Item_code ,QR_FIRST.total ,QR_FIRST.customer_code
// ***********************************
View นี้ให้ชื่อว่า ViewGetMaxItem ค่ะ
และที่ Command จะเขียนดังนี้ ( ไม่ต้องการ Field ไหนก็ลบออกนะคะ )
SELECT
CASE
WHEN QR_MAX.first_rec_id = QR_CUSTOMER.dynamic_id
THEN CONVERT(VARCHAR(50) ,QR_MAX.item_code)
ELSE ''
END AS item_code_label
,QR_CUSTOMER.item_code,QR_CUSTOMER.CUSTOMER_CODE as custmain
,QR_MAX.max_item ,QR_MAX.total_customer
,CASE
WHEN QR_MAX.first_rec_id = QR_CUSTOMER.dynamic_id
THEN QR_MAX.max_item
ELSE 0
END AS filter_max_item
,CASE
WHEN QR_MAX.first_rec_id = QR_CUSTOMER.dynamic_id
THEN QR_MAX.total_customer
ELSE 0
END AS filter_total_customer
,CASE
WHEN QR_MAX.first_rec_id = QR_CUSTOMER.dynamic_id
THEN ''
ELSE 'Not include by same maximum order'
END AS comment
FROM dbo.ViewGetMaxItem AS QR_CUSTOMER
RIGHT JOIN
(
SELECT QR_INNER.item_code, MAX(QR_INNER.total) AS max_item
,COUNT(QR_INNER.customer_code) AS total_customer
,MIN(QR_INNER.dynamic_id) as first_rec_id
FROM dbo.ViewGetMaxItem AS QR_INNER
GROUP BY QR_INNER.item_code
) AS QR_MAX
ON (QR_CUSTOMER.item_code=QR_MAX.item_code)
AND (QR_CUSTOMER.total = QR_MAX.max_item)
ORDER BY QR_CUSTOMER.item_code ,QR_CUSTOMER.CUSTOMER_CODE;
|
 |
 |
 |
 |
Date :
2010-03-03 23:08:17 |
By :
blurEye |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ขอบคุณมากค่ะ เด๋วจะลองทำดูนะค่ะ
|
 |
 |
 |
 |
Date :
2010-03-04 09:50:14 |
By :
Angel_baba |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
คุณ blurEye คะ row_number() นี่คืออะไรหรอคะ พอดีเอาคิวรี่ไปสร้างแล้วฟ้อง error ตรงนี้ค่ะ
แล้วก็ select case นี่อ่านไม่เข้าใจเลยค่ะ ไม่เคยใช้เลยค่ะ แต่ว่าลองเอา ตัวอย่างที่ 1 ไปใช้แล้วเลยอยากจะทราบว่ามีวิธีที่เข้าใจง่ายๆกว่านี้มั้ยคะ อย่างเช่น ให้ distinct itemcode อันไหนก็ได้อะค่ะ หรือต้องทำอย่างไรคะ
|
 |
 |
 |
 |
Date :
2010-03-07 18:38:27 |
By :
Angel_baba |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
row_number เป็น function ใน sql sever 2005 ขึ้นมา
ตัวอย่างที่เขียนให้ทำด้วย MS SQL SERVER
ถ้าเป็น MySQL หรือ PostgreSQL จะเขียนแตกต่างออกไป
ไม่ทราบใช้ฐานข้อมูลอะไรคะ
เพราะ เป็นความต้องการที่ซับซ้อน Query เลยต้องซับซ้อนตามไปด้วยค่ะ
พยายามจะไม่ให้ซับซ้อนแล้วค่ะ
|
 |
 |
 |
 |
Date :
2010-03-07 22:10:35 |
By :
blurEye |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ใช้ ms sql 2000 ค่ะ
|
 |
 |
 |
 |
Date :
2010-03-07 22:22:52 |
By :
Angel_baba |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ทำได้แล้วค่ะ แต่ต้องดัดแปลงหลายๆอย่าง ขอบคุณมากๆเลยนะค่ะ คุณ blurEye
|
 |
 |
 |
 |
Date :
2010-03-08 11:12:10 |
By :
Angel_baba |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ขอบคุณเช่นกันค่ะ ถ้ายังไงช่วยลง QUERY ที่ดัดแปลงด้วยสิคะจะได้เป็นการให้ความคิดกับปัญหาทำนองนี้ค่ะ
|
 |
 |
 |
 |
Date :
2010-03-08 12:33:00 |
By :
blurEye |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ที่ดัดแปลก็คือ สร้างวิวเรียก cusmain แล้วก็ไปสร้างตารางเก็บ cusmain ก่อน 1 ตาราง ซึ่งจะมี autonumberอยู่ด้วยค่ะ เพราะ sql 2000 มันคงใช้ rownumber() ไม่ได้
2. เอาคิวรี่ที่คุณ blureye มาใช้ค่ะ แล้วก็เก็บอีกทีค่ะ
|
 |
 |
 |
 |
Date :
2010-03-10 17:27:05 |
By :
Angel_baba |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
|
|