คอมพิวเตอร์ หน้าต่าง อินเทอร์เน็ต

แบบสอบถาม SQL จัดกลุ่มตาม การจัดกลุ่มข้อมูล Transact-SQL GROUP BY การจัดกลุ่มโดยใช้กลุ่มตามและการกรองกลุ่มที่มี

การจัดกลุ่มข้อมูลช่วยให้คุณสามารถแบ่งข้อมูลทั้งหมดออกเป็นชุดตรรกะ ทำให้สามารถคำนวณทางสถิติแยกกันในแต่ละกลุ่มได้

1. การสร้างกลุ่ม (GROUP BY)

กลุ่มถูกสร้างขึ้นโดยใช้ข้อเสนอ จัดกลุ่มตามตัวดำเนินการ เลือก. ลองดูตัวอย่าง

เลือก ผลิตภัณฑ์ SUM(ปริมาณ) AS Product_num จาก Sumproduct GROUP BY Product

ด้วยคำขอนี้ เราได้ดึงข้อมูลเกี่ยวกับจำนวนผลิตภัณฑ์ที่ขายในแต่ละเดือน ผู้ดำเนินการ เลือกสั่งให้เอาต์พุตสองคอลัมน์ ผลิตภัณฑ์- ชื่อผลิตภัณฑ์และ สินค้า_หมายเลข- ช่องคำนวณที่เราสร้างขึ้นเพื่อแสดงจำนวนสินค้าที่ขาย (ช่องสูตร SUM (Quantity)) เสนอ จัดกลุ่มตามบอกให้ DBMS จัดกลุ่มข้อมูลตามคอลัมน์ ผลิตภัณฑ์. นอกจากนี้ยังเป็นที่น่าสังเกตว่า จัดกลุ่มตามควรมาหลังประโยค ที่ไหนและก่อนหน้านั้น สั่งโดย.

2. กลุ่มตัวกรอง (HAVING)

เช่นเดียวกับที่เรากรองแถวในตาราง เราก็สามารถกรองข้อมูลที่จัดกลุ่มได้ เพื่อทำสิ่งนี้ใน SQLมีผู้ดำเนินการ มี. ลองใช้ตัวอย่างก่อนหน้านี้และเพิ่มการกรองตามกลุ่ม

เลือก ผลิตภัณฑ์ SUM(ปริมาณ) AS Product_num จากกลุ่มผลิตภัณฑ์ Sumproduct ตามผลิตภัณฑ์ที่มี SUM(ปริมาณ)>4000

เราจะเห็นว่าหลังจากคำนวณปริมาณสินค้าที่ขายสำหรับแต่ละผลิตภัณฑ์แล้ว DBMS จะ "ตัด" ผลิตภัณฑ์เหล่านั้นซึ่งมียอดขายน้อยกว่า 4,000 หน่วยออก

ดังที่เราเห็นผู้ดำเนินการ มีคล้ายกับตัวดำเนินการมาก ที่ไหนอย่างไรก็ตาม พวกเขามีความแตกต่างที่สำคัญระหว่างกัน: ที่ไหนกรองข้อมูลก่อนที่จะจัดกลุ่มและ มี- ทำการกรองหลังจากการจัดกลุ่ม ดังนั้นบรรทัดที่ถูกลบออกโดยข้อเสนอ ที่ไหนจะไม่ถูกรวมเข้ากลุ่ม ดังนั้นผู้ปฏิบัติงาน ที่ไหนและ มีสามารถใช้ในประโยคเดียวกันได้ ลองดูตัวอย่าง:

เลือก ผลิตภัณฑ์ SUM (ปริมาณ) AS Product_num จาก Sumproduct WHERE ผลิตภัณฑ์<>กลุ่ม "Skis Long" ตามผลิตภัณฑ์ซึ่งมียอดรวม(ปริมาณ)>4000

เราได้เพิ่มตัวดำเนินการลงในตัวอย่างก่อนหน้า ที่ไหนโดยระบุผลิตภัณฑ์ไว้ สกีลองซึ่งส่งผลต่อการจัดกลุ่มโดยผู้ปฏิบัติงาน มี. ส่งผลให้เราเห็นว่าสินค้านั้น สกีลองไม่รวมอยู่ในรายชื่อกลุ่มที่มีจำนวนสินค้าที่จำหน่ายเกิน 4,000 ชิ้น

3. การจัดกลุ่มและการเรียงลำดับ

เช่นเดียวกับการเรียกข้อมูลตามปกติ เราสามารถจัดเรียงกลุ่มหลังจากจัดกลุ่มกับผู้ปฏิบัติงานได้ มี. ในการดำเนินการนี้ เราสามารถใช้โอเปอเรเตอร์ที่เราคุ้นเคยอยู่แล้วได้ สั่งโดย. ในสถานการณ์นี้ แอปพลิเคชันจะคล้ายกับตัวอย่างก่อนหน้านี้ เช่น:

เลือก สินค้า, SUM(ปริมาณ) AS Product_num จากผลิตภัณฑ์รวม GROUP BY Product HAVING SUM(Quantity)>3000 ORDER BY SUM(Quantity)

หรือเพียงระบุหมายเลขฟิลด์ตามลำดับที่เราต้องการเรียงลำดับ:

เลือก ผลิตภัณฑ์ SUM(ปริมาณ) AS Product_num จากกลุ่มผลิตภัณฑ์ Sumproduct ตามผลิตภัณฑ์ที่มี SUM(ปริมาณ)>3000 เรียงลำดับตาม 2

เราเห็นว่าการจัดเรียงผลลัพธ์สรุปเราเพียงแค่ต้องเขียนประโยคด้วย สั่งโดยหลังจากผู้ปฏิบัติงาน มี. อย่างไรก็ตามมีข้อแม้ประการหนึ่ง เข้าถึง DBMSไม่รองรับการเรียงลำดับกลุ่มตามนามแฝงของคอลัมน์ กล่าวคือ ในตัวอย่างของเรา เพื่อที่จะเรียงลำดับค่า เราจะไม่สามารถเขียนต่อท้ายคำขอได้ เรียงตามสินค้า_num.

ในบทความนี้ ผมจะบอกคุณถึงวิธีการจัดกลุ่มข้อมูล วิธีใช้การจัดกลุ่มอย่างถูกต้องและการสืบค้นภายใน SQL โดยใช้ตัวอย่างการสืบค้นหลายรายการ

ข้อมูลในฐานข้อมูลส่วนใหญ่จะถูกจัดเก็บในรูปแบบรายละเอียด อย่างไรก็ตาม มักมีความจำเป็นต้องได้รับรายงาน ตัวอย่างเช่น ค้นหาจำนวนความคิดเห็นของผู้ใช้ทั้งหมดหรือจำนวนสินค้าในคลังสินค้า มีงานที่คล้ายกันมากมาย ดังนั้น ภาษา SQL จึงจัดให้มีกลุ่มโดยเฉพาะสำหรับกรณีดังกล่าวและมีโครงสร้าง ซึ่งอนุญาตให้จัดกลุ่มและกรองกลุ่มผลลัพธ์ของข้อมูลตามลำดับ

อย่างไรก็ตามการใช้งานทำให้เกิดปัญหามากมายสำหรับผู้เขียนซอฟต์แวร์มือใหม่ พวกเขาตีความผลลัพธ์ที่ได้รับและกลไกการจัดกลุ่มข้อมูลได้ไม่ถูกต้องนัก ดังนั้นเรามาดูในทางปฏิบัติว่าเกิดอะไรขึ้นและอย่างไร

ส่วนหนึ่งของตัวอย่าง ฉันจะพิจารณาเพียงตารางเดียว เหตุผลง่ายๆ คือ ตัวดำเนินการเหล่านี้ถูกนำไปใช้กับตัวอย่างข้อมูลผลลัพธ์แล้ว (หลังจากรวมแถวของตารางและกรองแล้ว) ดังนั้นการเพิ่มตำแหน่งและตัวดำเนินการเข้าร่วมจะไม่เปลี่ยนสาระสำคัญ

ลองจินตนาการถึงตัวอย่างที่เป็นนามธรรม สมมติว่าคุณมีตารางสรุปของผู้ใช้ฟอรั่ม ลองเรียกมันว่า userstat แล้วหน้าตาจะเป็นแบบนี้ จุดสำคัญคือเราเชื่อว่าผู้ใช้สามารถอยู่ในกลุ่มเดียวเท่านั้น

user_name - ชื่อผู้ใช้

forum_group - ชื่อกลุ่ม

Mess_count - จำนวนข้อความ

is_have_social_profile - ว่าโปรไฟล์ฟอรัมมีลิงก์ไปยังหน้าบนเครือข่ายโซเชียลหรือไม่

อย่างที่คุณเห็น ตารางนี้เรียบง่ายและคุณสามารถคำนวณหลาย ๆ อย่างได้ด้วยตัวเองโดยใช้เครื่องคิดเลข อย่างไรก็ตาม นี่เป็นเพียงตัวอย่างและมีเพียง 10 รายการเท่านั้น ในฐานข้อมูลจริง สามารถวัดบันทึกได้เป็นพัน เรามาเริ่มด้วยคำถามกันก่อน

การจัดกลุ่มล้วนๆ โดยใช้การจัดกลุ่มตาม

ลองจินตนาการว่าเราต้องรู้คุณค่าของแต่ละกลุ่ม ได้แก่ คะแนนเฉลี่ยของผู้ใช้ในกลุ่ม และจำนวนข้อความทั้งหมดที่เหลืออยู่ในฟอรัม

ขั้นแรก คำอธิบายด้วยวาจาสั้นๆ เพื่อให้เข้าใจแบบสอบถาม SQL ได้ง่ายขึ้น ดังนั้นคุณต้องค้นหาค่าที่คำนวณตามกลุ่มฟอรัม ดังนั้น คุณจะต้องแบ่งบรรทัดทั้งสิบบรรทัดนี้ออกเป็นสามกลุ่ม: ผู้ดูแลระบบ ผู้ควบคุม และผู้ใช้ ในการดำเนินการนี้ คุณต้องเพิ่มการจัดกลุ่มตามค่าของช่อง forum_group ที่ส่วนท้ายของคำขอ และยังเพิ่มนิพจน์จากการคำนวณเพื่อเลือกโดยใช้ฟังก์ชันที่เรียกว่าฟังก์ชันรวม

ระบุฟิลด์และคอลัมน์จากการคำนวณ เลือก forum_group, avg(raiting) เป็น avg_raiting, sum(mess_count) เป็น Total_mess_count -- ระบุตารางจาก userstat -- ระบุการจัดกลุ่มตามกลุ่มฟิลด์ตาม forum_group

โปรดทราบว่าหลังจากที่คุณใช้ group by build ในการสืบค้นแล้ว คุณจะสามารถใช้ได้เฉพาะฟิลด์เหล่านั้นในการเลือกที่ระบุไว้หลังกลุ่มโดยไม่ต้องใช้ฟังก์ชันรวม ต้องระบุฟิลด์ที่เหลือภายในฟังก์ชันการรวม

ฉันยังใช้ฟังก์ชันรวมสองฟังก์ชันด้วย AVG - คำนวณค่าเฉลี่ย และ SUM - คำนวณผลรวม

ฟอรั่ม_groupเฉลี่ย_เรตติ้งTotal_mess_count
ผู้ดูแลระบบ 4 50
ผู้ดูแล 3 50
ผู้ใช้ 3 150

1. ขั้นแรก แถวทั้งหมดของตารางต้นฉบับถูกแบ่งออกเป็นสามกลุ่มตามค่าของฟิลด์ forum_group ตัวอย่างเช่น มีผู้ใช้สามคนภายในกลุ่มผู้ดูแลระบบ ภายในโมเดอเรเตอร์ยังมี 3 บรรทัด และภายในกลุ่มผู้ใช้มี 4 บรรทัด (ผู้ใช้สี่คน)

2. จากนั้นนำฟังก์ชันรวมไปใช้กับแต่ละกลุ่ม ตัวอย่างเช่น สำหรับกลุ่มผู้ดูแลระบบ คะแนนเฉลี่ยคำนวณดังนี้ (2 + 5 + 5)/3 = 4 จำนวนข้อความคำนวณเป็น (10 + 15 + 25) = 50

อย่างที่คุณเห็นไม่มีอะไรซับซ้อน อย่างไรก็ตาม เราใช้เงื่อนไขการจัดกลุ่มเพียงเงื่อนไขเดียวและไม่ได้กรองตามกลุ่ม เรามาดูตัวอย่างถัดไปกันดีกว่า

การจัดกลุ่มโดยใช้กลุ่มตามและการกรองกลุ่มที่มี

ตอนนี้เรามาดูตัวอย่างการจัดกลุ่มข้อมูลที่ซับซ้อนมากขึ้น สมมติว่าเราจำเป็นต้องประเมินประสิทธิผลของการดำเนินการเพื่อดึงดูดผู้ใช้ให้เข้าร่วมกิจกรรมทางสังคม พูดง่ายๆ ก็คือค้นหาจำนวนผู้ใช้ในกลุ่มที่ทิ้งลิงก์ไปยังโปรไฟล์ของพวกเขา และจำนวนการส่งจดหมายที่ถูกละเว้น เป็นต้น อย่างไรก็ตาม ในชีวิตจริงอาจมีกลุ่มดังกล่าวอยู่เป็นจำนวนมาก ดังนั้นเราจึงจำเป็นต้องกรองกลุ่มที่อาจละเลยออกไป (เช่น มีคนจำนวนน้อยเกินไปที่ไม่ได้ทิ้งลิงก์ไว้ ทำไมต้องทำให้รายงานฉบับเต็มเกะกะ) ในตัวอย่างของฉัน กลุ่มเหล่านี้คือกลุ่มที่มีผู้ใช้เพียงคนเดียว

ขั้นแรก เราจะอธิบายด้วยวาจาถึงสิ่งที่ต้องทำในการสืบค้น SQL เราจำเป็นต้องแบ่งแถวทั้งหมดของตาราง userstat ดั้งเดิมตามเกณฑ์ต่อไปนี้: ชื่อกลุ่มและการมีอยู่ของโปรไฟล์โซเชียล ดังนั้นจึงจำเป็นต้องจัดกลุ่มข้อมูลตารางตามฟิลด์ forum_group และ is_have_social_profile แต่เราไม่สนใจกลุ่มที่มีคนเพียงคนเดียว จึงต้องกรองกลุ่มดังกล่าวออก

บันทึก: ควรรู้ว่าปัญหานี้สามารถแก้ไขได้ด้วยการจัดกลุ่มเพียงฟิลด์เดียว หากคุณใช้โครงสร้างเคส อย่างไรก็ตาม ภายในกรอบของตัวอย่างนี้ ความเป็นไปได้ของการจัดกลุ่มจะแสดงขึ้น

ฉันอยากจะชี้แจงประเด็นสำคัญประการหนึ่งทันที คุณสามารถกรองโดยใช้มีได้เมื่อใช้ฟังก์ชันรวมเท่านั้น ไม่ใช่ตามแต่ละฟิลด์ กล่าวอีกนัยหนึ่ง นี่ไม่ใช่โครงสร้างที่ แต่เป็นตัวกรองสำหรับกลุ่มของแถว ไม่ใช่แต่ละเรกคอร์ด แม้ว่าเงื่อนไขภายในจะระบุในลักษณะเดียวกันโดยใช้ "หรือ" และ "และ"

นี่คือลักษณะของแบบสอบถาม SQL

ระบุฟิลด์และคอลัมน์จากการคำนวณ เลือก forum_group, is_have_social_profile, count(*) เป็นผลรวม -- ระบุตารางจาก userstat -- ระบุการจัดกลุ่มตามกลุ่มฟิลด์ตาม forum_group, is_have_social_profile -- ระบุตัวกรองกลุ่มที่มี count(*) > 1

โปรดทราบว่าฟิลด์ที่อยู่หลังกลุ่มตามโครงสร้างจะถูกคั่นด้วยเครื่องหมายจุลภาค การระบุฟิลด์ในการเลือกเกิดขึ้นในลักษณะเดียวกับในตัวอย่างก่อนหน้านี้ ฉันยังใช้การนับฟังก์ชันรวม ซึ่งคำนวณจำนวนแถวในกลุ่ม

นี่คือผลลัพธ์:

ฟอรั่ม_groupis_have_social_profileทั้งหมด
ผู้ดูแลระบบ 1 2
ผู้ดูแล 1 2
ผู้ใช้ 0 3

มาดูทีละขั้นตอนว่าผลลัพธ์นี้เป็นอย่างไร

1. เบื้องต้นได้ 6 กลุ่ม แต่ละกลุ่ม forum_group ถูกแบ่งออกเป็นสองกลุ่มย่อยตามค่าของฟิลด์ is_have_social_profile กล่าวอีกนัยหนึ่ง กลุ่ม: , , , , , .

บันทึก: อย่างไรก็ตาม ไม่จำเป็นต้องมี 6 กลุ่ม ตัวอย่างเช่น หากผู้ดูแลระบบทั้งหมดกรอกโปรไฟล์ก็จะมี 5 กลุ่ม เนื่องจากช่อง is_have_social_profile จะมีเพียงค่าเดียวสำหรับผู้ใช้ของกลุ่มผู้ดูแลระบบ

2. จากนั้นนำเงื่อนไขการกรองที่มีไปใช้กับแต่ละกลุ่ม ดังนั้นจึงไม่รวมกลุ่มต่อไปนี้: , , . เนื่องจากภายในแต่ละกลุ่มจะมีตารางต้นฉบับเพียงแถวเดียวเท่านั้น

3. หลังจากนั้น ข้อมูลที่จำเป็นจะถูกคำนวณและได้รับผลลัพธ์

อย่างที่คุณเห็นไม่มีอะไรยากในการใช้งาน

เป็นเรื่องที่ควรรู้ว่าความสามารถของโครงสร้างเหล่านี้อาจแตกต่างกันขึ้นอยู่กับฐานข้อมูล ตัวอย่างเช่น อาจมีฟังก์ชันการรวมมากกว่า หรือคุณสามารถระบุคอลัมน์จากการคำนวณแทนที่จะเป็นแต่ละฟิลด์เป็นกลุ่มได้ ข้อมูลนี้จะต้องดูในข้อกำหนดแล้ว

ตอนนี้คุณรู้วิธีจัดกลุ่มข้อมูลด้วยการจัดกลุ่มตาม รวมถึงวิธีกรองกลุ่มโดยใช้การมี


อัปเดตครั้งล่าสุด: 07/19/2017

T-SQL ใช้คำสั่ง GROUP BY และ HAVING เพื่อจัดกลุ่มข้อมูล โดยใช้ไวยากรณ์ที่เป็นทางการต่อไปนี้:

เลือกคอลัมน์จากตาราง

จัดกลุ่มตาม

GROUP BY clause กำหนดวิธีการจัดกลุ่มแถว

ตัวอย่างเช่น ลองจัดกลุ่มผลิตภัณฑ์ตามผู้ผลิต

เลือกผู้ผลิต COUNT(*) AS Modelsนับจากกลุ่มผลิตภัณฑ์ตามผู้ผลิต

คอลัมน์แรกในคำสั่ง SELECT - ผู้ผลิต แสดงถึงชื่อของกลุ่ม และคอลัมน์ที่สอง - ModelsCount แสดงถึงผลลัพธ์ของฟังก์ชัน Count ซึ่งจะคำนวณจำนวนแถวในกลุ่ม

ควรพิจารณาว่าคอลัมน์ใดๆ ที่ใช้ในคำสั่ง SELECT (ไม่นับคอลัมน์ที่เก็บผลลัพธ์ของฟังก์ชันการรวม) จะต้องระบุหลังส่วนคำสั่ง GROUP BY ตัวอย่างเช่น ในกรณีข้างต้น คอลัมน์ผู้ผลิตจะถูกระบุไว้ในทั้งส่วนคำสั่ง SELECT และ GROUP BY

และถ้าคำสั่ง SELECT เลือกหนึ่งคอลัมน์ขึ้นไปและใช้ฟังก์ชันการรวมด้วย คุณต้องใช้ GROUP BY clause ดังนั้น ตัวอย่างต่อไปนี้จะไม่ทำงานเนื่องจากไม่มีนิพจน์การจัดกลุ่ม:

เลือกผู้ผลิต COUNT(*) AS Modelsนับจากผลิตภัณฑ์

อีกตัวอย่างหนึ่ง ลองเพิ่มการจัดกลุ่มตามจำนวนผลิตภัณฑ์:

เลือกผู้ผลิต, ProductCount, COUNT(*) AS ModelsCount จากกลุ่มผลิตภัณฑ์ตามผู้ผลิต, ProductCount

GROUP BY clause สามารถจัดกลุ่มได้หลายคอลัมน์

หากคอลัมน์ที่คุณกำลังจัดกลุ่มมีค่า NULL แถวที่มีค่า NULL จะแยกกลุ่มกัน

โปรดทราบว่า GROUP BY clause ต้องอยู่หลัง WHERE clause แต่อยู่ก่อน ORDER BY clause:

เลือกผู้ผลิต COUNT(*) AS ModelsCount จากผลิตภัณฑ์ WHERE ราคา > 30000 กลุ่มตามผู้ผลิต ORDER BY ModelsCount DESC

การกรองกลุ่ม มี

ผู้ดำเนินการ มี กำหนดกลุ่มที่จะรวมอยู่ในผลลัพธ์ผลลัพธ์ นั่นคือกรองกลุ่ม

การใช้ HAVING มีความคล้ายคลึงกับการใช้ WHERE ในหลายๆ ด้าน เฉพาะ WHERE เท่านั้นที่ใช้กรองแถว HAVING ใช้เพื่อกรองกลุ่ม

ตัวอย่างเช่น เรามาค้นหากลุ่มผลิตภัณฑ์ทั้งหมดตามผู้ผลิตซึ่งมีการกำหนดรุ่นไว้มากกว่า 1 รุ่น:

เลือกผู้ผลิต COUNT(*) AS Modelsนับจากกลุ่มผลิตภัณฑ์ตามผู้ผลิต มี COUNT(*) > 1

ในกรณีนี้ ในคำสั่งเดียวเราสามารถใช้นิพจน์ WHERE และ HAVING ได้:

เลือกผู้ผลิต COUNT(*) AS ModelsCount จากผลิตภัณฑ์ โดยที่ราคา * จำนวนผลิตภัณฑ์ > 80000 กลุ่มตามผู้ผลิต มี COUNT(*) > 1

นั่นคือในกรณีนี้ แถวต่างๆ จะถูกกรองก่อน: ผลิตภัณฑ์เหล่านั้นถูกเลือกซึ่งมีต้นทุนรวมมากกว่า 80,000 จากนั้น ผลิตภัณฑ์ที่เลือกจะถูกจัดกลุ่มตามผู้ผลิต จากนั้นกลุ่มจะถูกกรอง - เลือกกลุ่มที่มีมากกว่า 1 โมเดล

หากจำเป็นต้องเรียงลำดับ นิพจน์ ORDER BY จะอยู่หลังนิพจน์ HAVING:

เลือกผู้ผลิต, COUNT(*) AS Models, SUM(ProductCount) AS หน่วยจากผลิตภัณฑ์ WHERE ราคา * ProductCount > 80000 GROUP BY Manufacturing HAVING SUM(ProductCount) > 2 ORDER BY Units DESC

ในกรณีนี้ การจัดกลุ่มจะเป็นไปตามผู้ผลิต และเลือกจำนวนรุ่นสำหรับผู้ผลิตแต่ละราย (รุ่น) และจำนวนผลิตภัณฑ์ทั้งหมดสำหรับรุ่นเหล่านี้ทั้งหมด (หน่วย) ด้วยเช่นกัน ในตอนท้าย กลุ่มจะจัดเรียงตามจำนวนผลิตภัณฑ์จากมากไปน้อย

ในบทช่วยสอนนี้ คุณจะได้เรียนรู้วิธีใช้คำสั่ง SQL จัดกลุ่มตามพร้อมไวยากรณ์และตัวอย่าง

คำอธิบาย

สามารถใช้คำสั่งย่อย SQL GROUP BY ในคำสั่ง SELECT เพื่อรวบรวมข้อมูลจากหลายระเบียนและจัดกลุ่มผลลัพธ์ให้เป็นหนึ่งคอลัมน์ขึ้นไป

ไวยากรณ์

ไวยากรณ์สำหรับคำสั่ง GROUP BY ใน SQL คือ:

พารามิเตอร์หรืออาร์กิวเมนต์

expression1 , expression2 , … expression_n นิพจน์ที่ไม่ได้ห่อหุ้มไว้ในฟังก์ชันรวมและต้องรวมไว้ใน GROUP BY ที่ส่วนท้ายของแบบสอบถาม SQL integrated_function นี่คือฟังก์ชันรวม เช่น SUM, COUNT, MIN, MAX หรือ AVG การรวมนิพจน์ นี่คือคอลัมน์หรือนิพจน์ที่จะใช้การรวมฟังก์ชัน ตาราง ตารางที่คุณต้องการดึงข้อมูลบันทึก ส่วนคำสั่ง FROM ต้องระบุอย่างน้อยหนึ่งตาราง WHERE เงื่อนไข ไม่บังคับ นี่คือเงื่อนไขที่ต้องปฏิบัติตามเพื่อเลือกเรกคอร์ด ORDER BY นิพจน์ ไม่จำเป็น นิพจน์ที่ใช้ในการเรียงลำดับเรกคอร์ดในชุดผลลัพธ์ หากมีการระบุมากกว่าหนึ่งนิพจน์ ค่าจะต้องคั่นด้วยเครื่องหมายจุลภาค ตัวเลือก ASC ASC เรียงลำดับชุดผลลัพธ์จากน้อยไปหามากตามนิพจน์ นี่เป็นพฤติกรรมเริ่มต้นหากไม่มีการระบุตัวแก้ไข DESC เป็นตัวเลือก DESC เรียงลำดับชุดผลลัพธ์จากมากไปหาน้อยตามนิพจน์

ตัวอย่าง - การใช้ GROUP BY กับฟังก์ชัน SUM

มาดูวิธีใช้ GROUP BY กับฟังก์ชัน SUM ใน SQL กัน
ในตัวอย่างนี้ เรามีตารางพนักงานที่มีข้อมูลต่อไปนี้:

แผนก_id ยอดรวม_เงินเดือน
500 119500
501 113000

ในตัวอย่างนี้ เราใช้ฟังก์ชัน SUM เพื่อเพิ่มเงินเดือนทั้งหมดสำหรับแต่ละ dept_id และเราให้ผลลัพธ์ SUM(salary) เป็นนามแฝงของ "total_salaries" เนื่องจาก dept_id ไม่ได้ถูกห่อหุ้มไว้ในฟังก์ชัน SUM จึงต้องระบุในส่วนคำสั่ง GROUP BY

ตัวอย่าง - การใช้ GROUP BY กับฟังก์ชัน COUNT

เรามาดูวิธีการใช้ GROUP BY clause กับฟังก์ชัน COUNT ใน SQL กันดีกว่า

ในตัวอย่างนี้ เรามีตารางผลิตภัณฑ์ที่มีข้อมูลต่อไปนี้:

ในตัวอย่างนี้ เราใช้ฟังก์ชัน COUNT เพื่อคำนวณจำนวน Total_products สำหรับแต่ละ Category_id และเราระบุนามแฝง "total_products" เป็นผลลัพธ์ของฟังก์ชัน COUNT เรายกเว้นค่า category_id ทั้งหมดที่เป็น NULL โดยการกรองค่าเหล่านั้นในส่วนคำสั่ง WHERE เนื่องจาก category_id ไม่ได้ถูกห่อหุ้มไว้ในฟังก์ชัน COUNT จึงต้องระบุในส่วนคำสั่ง GROUP BY

ตัวอย่าง - การใช้ GROUP BY กับฟังก์ชัน MIN

ตอนนี้เรามาดูวิธีการใช้ GROUP BY clause กับฟังก์ชัน MIN ใน SQL

ในตัวอย่างนี้ เราจะใช้ตารางพนักงานอีกครั้งพร้อมข้อมูลต่อไปนี้:

2 รายการจะถูกเลือก นี่คือผลลัพธ์ที่คุณจะได้รับ:

แผนก_id ต่ำสุด_เงินเดือน
500 57500
501 42000

ในตัวอย่างนี้ เราใช้ฟังก์ชัน MIN เพื่อส่งกลับค่าเงินเดือนต่ำสุดสำหรับแต่ละ dept_id และเราใช้นามแฝงผลลัพธ์ของฟังก์ชัน MIN "lowest_salary" เนื่องจาก dept_id ไม่ได้ถูกห่อหุ้มไว้ในฟังก์ชัน MIN จึงต้องระบุในส่วนคำสั่ง GROUP BY

ตัวอย่าง - การใช้ GROUP BY กับฟังก์ชัน MAX

สุดท้ายนี้ เรามาดูวิธีใช้ GROUP BY clause กับฟังก์ชัน MAX กัน

ลองใช้ตารางพนักงานอีกครั้ง แต่คราวนี้ ค้นหาเงินเดือนสูงสุดสำหรับแต่ละ dept_id:

พนักงาน_หมายเลข ชื่อจริง นามสกุล เงินเดือน แผนก_id
1001 จัสติน บีเบอร์ 62000 500
1002 เซเลน่า โกเมซ 57500 500
1003 มิล่า คูนิส 71000 501
1004 ทอม ล่องเรือ 42000 501

ป้อนคำสั่ง SQL ต่อไปนี้

นามสกุล

ปีเกิด

อิวาโนวิช

เปโตรวิช

มิคาอิโลวิช

โบริโซวิช

นิโคเลฟน่า

ซิโดโรวา

แคทเธอรีน

อิวานอฟนา

วาเลนไทน์

เซอร์เกย์วิช

อนาโตลี

มิคาอิโลวิช

ข้าว. 4.20. ใช้ LIKE "^[DM]%"

ตอนนี้คุณสามารถสร้างเพรดิเคตในแง่ของความสัมพันธ์ SQL ที่กำหนดไว้เป็นพิเศษได้ คุณสามารถค้นหาค่าในช่วงเฉพาะ (BETWEEN) หรือชุดตัวเลข (IN) หรือคุณสามารถค้นหาค่าอักขระที่ตรงกับข้อความภายในพารามิเตอร์ (LIKE)

4.4. ฟังก์ชันรวม GROUP BY และ SQL

ผลลัพธ์ของแบบสอบถามอาจเป็นค่ากลุ่มทั่วไปของเขตข้อมูลได้ เช่นเดียวกับค่าของเขตข้อมูลเดียว ซึ่งทำได้โดยใช้ฟังก์ชันการรวม SQL มาตรฐาน ซึ่งมีรายการอยู่ด้านล่าง:

ยกเว้นกรณีพิเศษ COUNT(*) แต่ละฟังก์ชันเหล่านี้ทำงานกับคอลเลกชันของค่าในคอลัมน์ของบางตารางและสร้างค่าเพียงค่าเดียว

อาร์กิวเมนต์ของฟังก์ชันทั้งหมดยกเว้น COUNT(*) อาจนำหน้าด้วยคีย์เวิร์ด DISTINCT ซึ่งบ่งชี้ว่าค่าคอลัมน์ที่ซ้ำกัน

ต้องยกเว้นก่อนจึงจะสามารถใช้ฟังก์ชันได้ ฟังก์ชันพิเศษ COUNT(*) ใช้เพื่อนับแถวทั้งหมดในตารางโดยไม่มีข้อยกเว้น (รวมถึงรายการที่ซ้ำกัน)

ฟังก์ชันการรวมจะใช้คล้ายกับชื่อฟิลด์ในส่วนคำสั่งแบบสอบถาม SELECT โดยมีข้อยกเว้นประการหนึ่ง: ฟังก์ชันเหล่านี้ใช้ชื่อฟิลด์เป็นอาร์กิวเมนต์ เฉพาะช่องตัวเลขเท่านั้นที่สามารถใช้ได้กับ SUM และ AVG

สามารถใช้ทั้งช่องตัวเลขและอักขระกับ COUNT, MAX และ MIN เมื่อใช้กับฟิลด์อักขระ MAX และ MIN จะแปลเป็นโค้ด ASCII ที่เทียบเท่ากัน ซึ่งควรสื่อสารว่า MIN จะหมายถึงค่าแรกและ MAX เป็นค่าสุดท้ายตามลำดับตัวอักษร

หากต้องการค้นหา SUM ของเงินเดือนทั้งหมดในตาราง DEPARTMENT_EMPLOYEE (รูปที่ 2.3) คุณต้องป้อนข้อความค้นหาต่อไปนี้:

จากแผนก_ พนักงาน;

และบนหน้าจอเราจะเห็นผลลัพธ์: 46800 (ตารางจะมีหนึ่งคอลัมน์ชื่อ SUM)

การคำนวณมูลค่าเงินเดือนโดยเฉลี่ยก็ทำได้ง่ายเช่นกัน:

เลือก AVG ((เงินเดือน))

จากแผนก_ พนักงาน;

ฟังก์ชัน COUNT แตกต่างจากฟังก์ชันอื่นๆ เล็กน้อย นับจำนวนค่าในคอลัมน์ที่กำหนดหรือจำนวนแถวในตาราง เมื่อนับค่าของคอลัมน์จะใช้กับ DISTINCT เพื่อนับจำนวนค่าที่ไม่ซ้ำในฟิลด์ที่กำหนด

ตารางมีแปดแถวซึ่งมีมูลค่าเงินเดือนต่างกัน

โปรดทราบว่าสามตัวอย่างสุดท้ายยังคำนึงถึงข้อมูลบัญชีเกี่ยวกับพนักงานที่ถูกไล่ออกด้วย

ประโยคต่อไปนี้ช่วยให้คุณกำหนดจำนวนดิวิชั่นต่อได้

DISTINCT ตามด้วยชื่อของเขตข้อมูลที่ใช้ โดยอยู่ในวงเล็บ โดยมี COUNT ใช้กับแต่ละคอลัมน์

เลือกนับ (*)

จากแผนก_ พนักงาน;

คำตอบจะเป็น:

COUNT(*) นับแต่ละแถวในตาราง

DISTINCT ใช้ไม่ได้กับ COUNT (*)

สมมติว่าตาราง PAYMENT_STATE (รูปที่ 2.4) มีอีกหนึ่งคอลัมน์ที่เก็บจำนวนเงินที่หัก (ฟิลด์การหักเงิน) สำหรับแต่ละบรรทัดของคำสั่ง จากนั้น หากคุณสนใจจำนวนเงินทั้งหมด จะต้องรวมเนื้อหาของคอลัมน์จำนวนเงินและการหักลดเข้าด้วยกัน

หากคุณสนใจจำนวนเงินสูงสุดโดยคำนึงถึงการหักเงินที่มีอยู่ในใบแจ้งยอดซึ่งสามารถทำได้โดยใช้ประโยคต่อไปนี้:

เลือกสูงสุด (ผลรวม + การหักเงิน)

จาก Pay_sheet;

สำหรับแต่ละแถวในตาราง แบบสอบถามนี้จะเพิ่มค่าของเขตข้อมูลจำนวนเงินพร้อมกับค่าของเขตข้อมูลการหักเงิน และเลือกค่าที่มากที่สุดที่พบ

จัดกลุ่มตามข้อ (การจัดเรียงใหม่ ลำดับ)

ส่วนคำสั่ง GROUP BY ช่วยให้คุณสามารถกำหนดชุดย่อยของค่าในฟิลด์ใดฟิลด์หนึ่งในแง่ของฟิลด์อื่น และใช้ฟังก์ชันการรวมกับเซ็ตย่อย ซึ่งทำให้สามารถรวมเขตข้อมูลและฟังก์ชันการรวมไว้ในส่วนคำสั่ง SELECT เดียวได้

ตัวอย่างเช่น สมมติว่าคุณต้องการกำหนดจำนวนพนักงานในแต่ละแผนก (คำตอบแสดงในรูปที่ 4.21):

SELECT Department_ID, COUNT (DISTINCT Department_ID) AS จำนวน_พนักงาน

แผนก_พนักงาน

วันที่เลิกจ้าง

จำนวนพนักงาน

ส่วนคำสั่ง GROUP BY จะเหลือเฉพาะค่าคอลัมน์ที่ไม่ซ้ำ โดยเรียงลำดับจากน้อยไปมากตามค่าเริ่มต้น ในแง่นี้ GROUP BY clause แตกต่างจาก ORDER BY clause ตรงที่ส่วนหลัง แม้ว่าจะเรียงลำดับเร็กคอร์ดจากน้อยไปมาก แต่ก็ไม่ได้ลบค่าที่ซ้ำกันออก ในตัวอย่างที่กำหนด การสืบค้นจะจัดกลุ่มแถวของตารางตามค่าของคอลัมน์ Dept_ID (ตามหมายเลขแผนก) แถวที่มีหมายเลขแผนกเดียวกันจะถูกรวมเป็นกลุ่มก่อน แต่จะแสดงเพียงแถวเดียวสำหรับแต่ละกลุ่ม คอลัมน์ที่สองแสดงจำนวนแถวในแต่ละกลุ่ม เช่น จำนวนพนักงานในแต่ละแผนก

ตามคำจำกัดความ ค่าของเขตข้อมูลที่ใช้ GROUP BY จะมีค่าเพียงค่าเดียวต่อกลุ่มเอาต์พุต เช่นเดียวกับฟังก์ชันการรวม ผลลัพธ์คือความเข้ากันได้ที่อนุญาตให้รวมการรวมและฟิลด์ในลักษณะนี้

ตัวอย่างเช่น ให้ตาราง PAYMENT_LIST มีลักษณะดังนี้ Fig. 4.22 และเราต้องการกำหนดจำนวนเงินสูงสุดที่จ่ายให้กับพนักงานแต่ละคน

ประเภทการชำระเงิน

เป็นผลให้เราได้รับ

ข้าว. 4.23. ฟังก์ชันการรวมกับ AS

การจัดกลุ่มสามารถทำได้โดยใช้คุณลักษณะหลายประการ:

จากแผ่นงาน 1

จัดกลุ่มตาม Employee_id วันที่;

ผลลัพธ์:

ข้าว. 4.24. การจัดกลุ่มตามแอตทริบิวต์หลายรายการ

หากจำเป็นต้องจำกัดจำนวนกลุ่มที่ได้รับหลังจาก GROUP BY ให้ใช้คำสั่งย่อย HAVING คุณสามารถนำสิ่งนี้ไปใช้

4.5. การใช้วลี HAVING

ส่วนคำสั่ง HAVING มีบทบาทเดียวกันกับกลุ่ม เช่นเดียวกับส่วนคำสั่ง WHERE ทำหน้าที่สำหรับแถว: ใช้เพื่อแยกกลุ่ม เช่นเดียวกับที่ WHERE ใช้เพื่อแยกแถว วลีนี้รวมอยู่ในประโยค

เฉพาะในกรณีที่มีส่วนคำสั่ง GROUP BY และนิพจน์ใน HAVING ต้องใช้ค่าเดียวสำหรับกลุ่ม

ตัวอย่างเช่น สมมติว่าเราต้องแสดงองค์ประกอบเชิงปริมาณของทุกแผนก (รูปที่ 2.3) ยกเว้นแผนกหมายเลข 3

SELECT Department_ID, COUNT (DISTINCT Department_ID) AS จำนวน _พนักงาน

แผนก_พนักงาน

วันที่เลิกจ้าง

มี ID_แผนก< > 3;

จำนวนพนักงาน

องค์ประกอบสุดท้ายเมื่อประเมินนิพจน์ตารางคือส่วน HAVING (ถ้ามี) ไวยากรณ์สำหรับส่วนนี้เป็นดังนี้:

::=

มี

เงื่อนไขการค้นหาในส่วนนี้จะระบุเงื่อนไขในกลุ่มแถวในตารางที่จัดกลุ่ม อย่างเป็นทางการ ส่วน HAVING ยังสามารถแสดงในนิพจน์ตารางที่ไม่มี GROUP BY ได้ ในกรณีนี้ ผลลัพธ์ของการคำนวณพาร์ติชั่นก่อนหน้าจะถือว่าเป็นตารางที่จัดกลุ่มซึ่งประกอบด้วยกลุ่มเดียวที่ไม่มีคอลัมน์การจัดกลุ่มเฉพาะ

เงื่อนไขการค้นหาคำสั่งย่อย HAVING เป็นไปตามกฎวากยสัมพันธ์เดียวกันกับเงื่อนไขการค้นหาคำสั่งย่อย WHERE และสามารถรวมเพรดิเคตเดียวกันได้

อย่างไรก็ตาม มีข้อจำกัดทางวากยสัมพันธ์พิเศษเกี่ยวกับการใช้ในเงื่อนไขการค้นหาข้อกำหนดเฉพาะของคอลัมน์ตารางจากส่วนคำสั่ง FROM ของนิพจน์ตารางที่กำหนด ข้อจำกัดเหล่านี้เกิดจากการที่เงื่อนไขการค้นหาในส่วน HAVING เป็นการกำหนดเงื่อนไขสำหรับทั้งกลุ่ม ไม่ใช่สำหรับแต่ละแถว

ดังนั้น เฉพาะข้อกำหนดเฉพาะของคอลัมน์ที่ระบุเป็นคอลัมน์การจัดกลุ่มใน GROUP BY clause เท่านั้นที่สามารถนำมาใช้โดยตรงในนิพจน์ทางคณิตศาสตร์เพรดิเคตที่รวมอยู่ใน clause การเลือกของ HAVING clause คอลัมน์ที่เหลือสามารถระบุได้เฉพาะภายในข้อกำหนดของฟังก์ชันรวม COUNT, SUM, AVG, MIN และ MAX เท่านั้น ซึ่งในกรณีนี้จะคำนวณค่ารวมบางส่วนสำหรับทั้งกลุ่มแถว สถานการณ์จะคล้ายกับแบบสอบถามย่อยที่รวมอยู่ในเพรดิเคตของเงื่อนไขการเลือกของส่วน HAVING: หากแบบสอบถามย่อยใช้คุณลักษณะของกลุ่มปัจจุบัน จะสามารถระบุได้โดยการอ้างอิงถึงคอลัมน์การจัดกลุ่มเท่านั้น

ปล่อยให้แบบสอบถามอยู่ในรูปแบบ (สำหรับตารางฐานดูรูปที่ 4.22):

เลือก Employee_id, วันที่, MAX ((จำนวน))

จากแผ่นงาน 1

จัดกลุ่มตาม Employee_id วันที่;

มีความจำเป็นต้องชี้แจงเพื่อให้แสดงเฉพาะการชำระเงินที่เกิน 1,000 เท่านั้น

อย่างไรก็ตาม ตามมาตรฐาน การใช้ฟังก์ชันการรวมในส่วนคำสั่ง WHERE ถือเป็นสิ่งผิดกฎหมาย (เว้นแต่คุณจะใช้แบบสอบถามย่อย ซึ่งจะอธิบายในภายหลัง) เนื่องจากภาคแสดงจะได้รับการประเมินในรูปของแถวเดียว และฟังก์ชันการรวมจะถูกประเมินในรูปของกลุ่มของแถว .

ประโยคต่อไปนี้จะไม่ถูกต้อง:

เลือก Id_id, วันที่, MAX (จำนวนเงิน)

จากแผ่นงาน 1

โดยที่ MAX ((ผลรวม)) > 1,000 GROUP BY Comp_Id, วันที่;

ประโยคที่ถูกต้องจะเป็น:

เลือก Employee_id, วันที่, MAX ((จำนวน))