การเรียกดูข้อมูลโดยใช้ฟังก์ชันในการรวมมีรูปแบบดังนี้
SELECT <column 1, column 2, >
FROM <table name>
[WHERE<condition>]
[GROUP BY < grouping column> ]
[HAVING<condition>];
SELECT คำสั่งที่ต้องมีทุกครั้งที่ต้องการเรียกค้นข้อมูล
column 1, column 2, คอลัมน์ที่ต้องการเรียกค้น
FROM การกำหนดว่าให้เรียกดูข้อมูล ได้จากตารางใดบ้าง
table name ชื่อตารางที่ต้องการเรียกค้นข้อมูล
WHERE<condition> ส่วนของคำสั่งที่บอกเงื่อนไขที่จะใช้ในการค้นหาข้อมูล
GROUP BY < grouping column> ส่วนของคำสั่งที่บอกเงื่อนไขการจัดกลุ่ม
HAVING<condition> ใช้ควบคู่กันกับ GROUP BY เสมอ เพื่อต้องการให้ได้ข้อมูลที่จัดกลุ่มตาม GROUP BY
การเรียกดูข้อมูลโดยใช้อนุประโยค GROUP BY อนุประโยค GROUP BY เป็นคำสั่งในการกำหนดค่าต่าง ๆ ในคอลัมน์ใดคอลัมน์หนึ่งโดยเฉพาะในรูปของอีกคอลัมน์หนึ่ง ซึ่งใช้จัดเรียงข้อมูลที่มีความสัมพันธ์กันตามเงื่อนไข ข้อมูลที่ต้องการจัดกลุ่มนั้นและ ต้องสามารถรวมกลุ่มกันได้ด้วย คำสั่ง GROUP BY เป็นคำสั่งที่ใช้ในการจัดแถวข้อมูลตามคอลัมน์ที่ระบุหลัง GROUP BY โดยข้อมูลที่เหมือนกันจะจัดให้อยู่ในหมู่เดียวกัน
ตัวอย่างตาราง CHECKS
CHECK# |
PAYEE |
AMOUNT |
REMARKS |
1 |
Malee Benjanee |
150 |
Have sons next time |
2 |
Reading R.R. |
24534 |
Train to Chiangmai |
3 |
Malee Benjanee |
20032 |
Cellular Phone |
4 |
Surasit Utilities |
98 |
Gas |
5 |
Jintana $ Mitree |
150 |
Groceries |
16 |
Cash |
25 |
Wild Night Out |
17 |
Benjawan Gas |
251 |
Gas |
9 |
Arun Cleaners |
2435 |
X-Tra Starch |
20 |
Arun Cleaners |
105 |
All Dry clean |
8 |
Cash |
60 |
Trip to Saraburi |
21 |
Cash |
34 |
Trip to Nonthaburi |
30 |
Surasit Utilities |
875 |
Water |
31 |
Surasit Utilities |
34 |
Sewer |
25 |
Benjawan Gas |
1575 |
Gas |
SELECT PAYEE, SUM(AMOUNT)
FROM CHECKS;
ถ้าไม่ใช่ GROUP BY ในการรวมคอลัมน์ AMOUNT ของแต่ละคน จะเกิด ERROR ดังนี้
ผลลัพธ์
Dynamic SQL Error |
-SQL error code = -104 |
-invalid column reference |
จากตัวอย่างข้างตัน ถ้าต้องการนับว่า PAYEE แต่ละคนมีจำนวนค่าใช้จ่ายกี่ครั้งจะใช้คำสั่งดังนี้
SELECT PAYEE, SUM(AMOUNT), COUNT(PAYEE)
FROM CHECKS
GROUP BY PAYEE;
ผลลัพธ์
PAYEE |
SUM |
COUNT |
Arun Cleaners |
2540 |
2 |
Cash |
119 |
3 |
Benjawan Gas |
1826 |
2 |
Jintana $ Mitree |
150 |
1 |
Surasit Utilities |
1007 |
3 |
Malee Benjanee |
10182 |
2 |
Reading R.R. |
24534 |
1 |
ตัวอย่างตาราง ORGCHART
NAME |
TEAM |
SALARY |
SICKLEAVE |
ANNUALLEAVE |
ASAMS |
RESEARCH |
34000.00 |
34 |
12 |
WILKES |
MARKETING |
31000.00 |
40 |
9 |
STOKES |
MARKETING |
36000.00 |
20 |
19 |
MEZA |
COLLECTIONS |
40000.00 |
30 |
27 |
SIRIWAN |
RESEARCH |
45000.00 |
20 |
17 |
RICHARDSON |
MARKETING |
42000.00 |
25 |
18 |
FURY |
COLLECTIONS |
35000.00 |
22 |
14 |
PRECOURT |
PR |
37500.00 |
24 |
24 |
ถ้าต้องการหาค่าเฉลี่ยของ SALARY ของ TEAM งานแต่ละTEAM จะใช้คำสั่งดังนี้
SELECT TEAM, AVG(SALARY)
FROM ORGCHART
GROUP BY TEAM;
ผลลัพธ์
TEAM |
AVG |
COLLECTIONS |
37500.00 |
MARKETING |
36333.33 |
PR |
37500.00 |
RESEARCH |
39500.00 |
การเรียกดูข้อมูลแบบ HAVING HAVING จะใช้ควบคู่กันกับ GROUP BY เสมอ เพื่อต้องการให้ได้ข้อมูลที่จัดกลุ่มตาม GROUP BYเพียงบางส่วนตามเงื่อนไขที่ระบุไว้ใน HAVING
จากตัวอย่างที่ผ่านมาถ้าต้องการดูเงินเดือนเฉลื่ยของทีมงานที่มีค่าน้อยกว่า 38000 จะใช้คำสั่งดังนี้
SELECT TEAM, AVG(SALARY)
FROM ORGCHART
GROUP BY TEAM
HAVING AVG(SALARY) < 38000;
ผลลัพธ์
TEAM |
AVG |
PR |
37500.00 |
ตัวอย่าง การใช้ GROUP BY และ HAVING ร่วมกับคำสั่ง AND คือดูว่าทีมงานใดมีค่าเฉลี่ยของ SICKLEAVE มากกว่า 25 และ มีค่าเฉลี่ยของ ANNUALLEAVE น้อยกว่า 20 จะใช้คำสั่งดังนี้
SELECT TEAM, AVG(SICKLEAVE), AVG(ANNUALLEAVE)
FROM ORGCHART
GROUP BY TEAM
HAVING AVG(SICKLEAVE) >25 AND
AVG(ANNUALLEAVE) <20;
ผลลัพธ์
TEAM |
AVG |
AVG |
MARKETING |
28 |
15 |
RESEARCH |
27 |
15 |
ตัวอย่าง ถ้าต้องการหาค่าเฉลี่ยของ SICKLEAVE และค่าเฉลี่ยของ ANNUALLEAVE ของจำนวนทีมที่มีจำนวน row มากกว่า 1 จะใช้คำสั่งดังนี้
SELECT TEAM, AVG(SICKLEAVE), AVG(ANNUALLEAVE)
FROM ORGCHART
GROUP BY TEAM
HAVING COUNT(TEAM) > 1;
ผลลัพธ์
TEAM |
AVG |
AVG |
COLLECTIONS |
26 |
21 |
MARKETING |
28 |
15 |
RESEARCH |
27 |
15 |
การจัดทำฐานข้อมูลในรูปตารางเกิดจากการที่ข้อมูลได้ออกแบบมาเพื่อลดความซ้ำซ้อน(normalization) ดังนั้นข้อมูลที่มีรายละเอียดของข้อมูลมากอาจะถูกเก็บไว้ในหลายๆตารางแยกออกมาต่างหาก เช่น ตารางข้อมูลที่เป็นตารางหลัก(master table) และ ตารางข้อมูลที่เป็นตารางเชิงรายการ (transaction table) และตารางข้อมูลที่เป็นตารางที่อยู่(address table) เป็นต้น การแยกออกเป็นตารางข้อมูลย่อยๆนี้นอกจากลดความซ้ำซ้อน แล้วยังช่วยในการประหยัดเนื้อที่ และยังเพิ่มประสิทธิภาพของฐานข้อมูล
การเรียกค้นข้อมูลจากหลายตารางของภาษา SQL เป็นการกำหนดความสัมพันธ์ระหว่างตารางทั้งหลาย โดยสามารถเอาข้อมูลในตารางกี่ตารางก็ได้ให้มาสัมพันธ์กัน ดังนั้นจึงสามารถเชื่อมต่อข้อมูลที่แตกต่างกันได้โดยการใช้คำสั่ง WHERE คำสั่ง WHERE เป็นคำสั่งในการกำหนดเงื่อนไขในการเรียกดูข้อมูลใช้คู่กับคำสั่ง SELECT และ FROM
ตัวอย่างTABLE1
ROW |
REMARK |
Row 1 |
Table 1 |
Row 2 |
Table 1 |
Row 3 |
Table 1 |
Row 4 |
Table 1 |
Row 5 |
Table 1 |
Row 6 |
Table 1 |
ตัวอย่าง TABLE 2
ROW |
REMARK |
Row 1 |
Table 2 |
Row 2 |
Table 2 |
Row 3 |
Table 2 |
Row 4 |
Table 2 |
Row 5 |
Table 2 |
Row 6 |
Table 2 |
ถ้าต้องการรวมทั้ง 2 ตารางเข้าด้วยกัน
SELECT * FROM TABLE1, TABLES2
ผลลัพธ์
ROW |
REMARK |
ROW |
REMARK |
Row 1 |
Table 1 |
Row 1 |
Table 2 |
Row 1 |
Table 1 |
Row 2 |
Table 2 |
Row 1 |
Table 1 |
Row 3 |
Table 2 |
Row 1 |
Table 1 |
Row 4 |
Table 2 |
Row 1 |
Table 1 |
Row 5 |
Table 2 |
Row 1 |
Table 1 |
Row 6 |
Table 2 |
Row 2 |
Table 1 |
Row 1 |
Table 2 |
Row 2 |
Table 1 |
Row 2 |
Table 2 |
Row 2 |
Table 1 |
Row 3 |
Table 2 |
Row 2 |
Table 1 |
Row 4 |
Table 2 |
Row 2 |
Table 1 |
Row 5 |
Table 2 |
Row 2 |
Table 1 |
Row 6 |
Table 2 |
Row 3 |
Table 1 |
Row 1 |
Table 2 |
Row 3 |
Table 1 |
Row 2 |
Table 2 |
Row 3 |
Table 1 |
Row 3 |
Table 2 |
Row 3 |
Table 1 |
Row 4 |
Table 2 |
Row 3 |
Table 1 |
Row 5 |
Table 2 |
Row 3 |
Table 1 |
Row 6 |
Table 2 |
Row 4 |
Table 1 |
Row 1 |
Table 2 |
Row 4 |
Table 1 |
Row 2 |
Table 2 |
Row 4 |
Table 1 |
Row 3 |
Table 2 |
Row 4 |
Table 1 |
Row 4 |
Table 2 |
Row 4 |
Table 1 |
Row 5 |
Table 2 |
Row 4 |
Table 1 |
Row 6 |
Table 2 |
Row 5 |
Table 1 |
Row 1 |
Table 2 |
Row 5 |
Table 1 |
Row 2 |
Table 2 |
Row 5 |
Table 1 |
Row 3 |
Table 2 |
Row 5 |
Table 1 |
Row 4 |
Table 2 |
Row 5 |
Table 1 |
Row 5 |
Table 2 |
Row 5 |
Table 1 |
Row 6 |
Table 2 |
Row 6 |
Table 1 |
Row 1 |
Table 2 |
Row 6 |
Table 1 |
Row 2 |
Table 2 |
Row 6 |
Table 1 |
Row 3 |
Table 2 |
Row 6 |
Table 1 |
Row 4 |
Table 2 |
Row 6 |
Table 1 |
Row 5 |
Table 2 |
Row 6 |
Table 1 |
Row 6 |
Table 2 |
การเรียกดูข้อมูลแบบซ้อนกัน(subqueies) เป็นการสร้างคำสั่ง SELECT ซ้อนกัน การเรียกดูข้อมูลแบบซ้อนกันมีจุดประสงค์เพื่อลดภาระในการเชื่อมตารางที่ต้องใช้ในหน่วยความจำเป็นจำนวนมาก คำสั่งย่อยนี้สามารถสร้างหลังคำสั่ง WHERE มีรูปแบบดังนี้
SELECT [*] <column 1, column 2, >
FROM <table name>
[WHERE<column list = <Select Statement>]
SELECT คำสั่งที่ต้องมีทุกครั้งที่ต้องการเรียกค้นข้อมูล
column 1, column 2, คอลัมน์ที่ต้องการเรียกค้น
FROM การกำหนดว่าให้เรียกดูข้อมูล ได้จากตารางใดบ้าง
table name ชื่อตารางที่ต้องการเรียกค้นข้อมูล
WHERE<condition> ส่วนของคำสั่งที่บอกเงื่อนไขที่จะใช้ในการค้นหาข้อมูล
Select Statement ส่วนของคำสั่งที่เรียกค้นข้อมูลตามเงื่อนไข
การทำงานของคำสั่งย่อยที่ใช้ในการระบุเงื่อนไขหรือเรียกข้อมูลจะทำจากคำถามย่อยด้านในสุดผลที่ได้จะเป็นค่ากลับมาให้กับค่าที่อยู่หน้าเครื่องหมายเท่ากับ เพื่อเรียกค้นข้อมูล( SELECT )ตามต้องการ
ตัวอย่าง ถ้าต้องการหาคำสั่งซื้อของพนักงานขายที่อาศัยอยู่ใน Bangkok
SELECT *
FROM ORDERSTAB
WHERE SALENO IN
(SELECT SALENO
FROM SALETAB
WHERE ADDRESS = Bangkok);
ผลของคำสั่งจะได้ตารงดังนึ้
ตารางคำสั่งซึ้อสินค้า
ORDERNO |
AMT |
ORDERDATE |
CUSNO |
SALENO |
3001 |
1869 |
6/03/2000 |
2008 |
1007 |
3003 |
76719 |
6/03/2000 |
2001 |
1001 |
3002 |
190010 |
6/03/2000 |
2007 |
1004 |
3005 |
516045 |
6/03/2000 |
2003 |
1002 |
3006 |
109816 |
6/03/2000 |
2008 |
1007 |
3009 |
171323 |
6/04/2000 |
2002 |
1003 |
3007 |
7573 |
6/04/2000 |
2004 |
1002 |
3008 |
472300 |
6/05/2000 |
2006 |
1001 |
3010 |
130995 |
6/06/2000 |
2004 |
1002 |
3011 |
989198 |
6/06/2000 |
2006 |
1001 |
ตารางพนักงานขาย
SALENO |
SALENAME |
ADDRESS |
SALECOM |
1001 |
Chaiwat |
Bangkok |
0.12 |
1002 |
Mitree |
Puket |
0.13 |
1004 |
Benjawan |
Bangkok |
0.11 |
1007 |
Kanjana |
Chiangmai |
0.15 |
1003 |
Ternjai |
Nonthaburi |
0.10 |
ORDERNO |
AMT |
ORDERDATE |
CUSNO |
SALENO |
3003 |
76719 |
6/03/2000 |
2001 |
1001 |
3002 |
190010 |
6/03/2000 |
2007 |
1004 |
3008 |
472300 |
6/05/2000 |
2006 |
1001 |
3011 |
989198 |
6/06/2000 |
2006 |
1001 |
จากตัวอย่างนี้สามารถใช้คำสั่งที่ง่ายกว่าและได้ผลลัพธ์เหมือนกันคือ
SELECT ORDERNO AMT ORDERDATE CUSNO ORDERSTAB. SALENO
FROM ORDERSTAB, SALETAB
WHERE ORDERSTAB.SALENO SALETAB.SALENO
AND SALETAB.ADDRESS = Bangkok;
ตัวอย่าง ตาราง PART
PARTNUM |
DESCRIPTION |
PRICE |
54 |
PEDALS |
54.25 |
42 |
SEATS |
24.50 |
46 |
TIRES |
15.25 |
23 |
MOUNTAIN BIKE |
350.45 |
76 |
ROAD BIKE |
530.00 |
10 |
TANDEM |
1200.00 |
ตัวอย่างตาราง ORDERS
ORDEREDON |
NAME |
PARTNUM |
QUANTITY |
REMARKS |
15-MAY-2001 |
TRUE WHEEL |
23 |
6 |
PAID |
19-MAY-2001 |
TRUE WHEEL |
76 |
3 |
PAID |
2-SEP-2001 |
TRUE WHEEL |
10 |
1 |
PAID |
30-JUN-2001 |
BIKE SPEC |
54 |
10 |
PAID |
30-MAY-2001 |
BIKE SPEC |
10 |
2 |
PAID |
30-MAY-2001 |
BIKE SPEC |
23 |
8 |
PAID |
17-JAN-2001 |
BIKE SPEC |
76 |
11 |
PAID |
17-JAN-2001 |
LE SHOPPE |
76 |
5 |
PAID |
1-JUN-2001 |
LE SHOPPE |
10 |
3 |
PAID |
1-JUN-2001 |
AAA BIKE |
10 |
1 |
PAID |
1-JUN-2001 |
AAA BIKE |
76 |
4 |
PAID |
1-JUN-2001 |
AAA BIKE |
46 |
14 |
PAID |
11-JUN-2001 |
JACKS BIKE |
76 |
14 |
PAID |
SELECT *
FROM ORDERS
WHERE PARTNUM =
(SELECT PARTNUM
FROM PART
WHERE DESCRIPTION LIKE ROAD%)
ผลลัพธ์
ORDEREDON |
NAME |
PARTNUM |
QUANTITY |
REMARKS |
19-MAY-2001 |
TRUE WHEEL |
76 |
3 |
PAID |
17-JAN-2001 |
BIKE SPEC |
76 |
11 |
PAID |
17-JAN-2001 |
LE SHOPPE |
76 |
5 |
PAID |
1-JUN-2001 |
AAA BIKE |
76 |
4 |
PAID |
11-JUN-2001 |
JACKS BIKE |
76 |
14 |
PAID |