CH8: ADVANCED QUERY S A Y A N U N A N K A R D2 / 2 5 5 7
www. i t sc i .m ju .ac . th /sayan
RELATIONAL SET OPERATORS
ค ำสัง่ UNION, INTERSECT และ MINUS ถูกพฒันำใหใ้ชง้ำนในฐำนขอ้มลูของ ORACLE ดงัน้ัน
บำงค ำสัง่อำจจะไม่สำมำรถใชง้ำนไดใ้นระบบฐำนขอ้มลูอ่ืนๆ
ขอ้มูลของทั้งสองตำรำงท่ีจะท ำกำร UNION หรือ INTERSECT หรือ MINUS จะตอ้งมีช่ือคอลมัน์
เดียวกนั และชนิดขอ้มลูเดียวกนั แต่ในบำงระบบจดักำรฐำนขอ้มลู อำจจะอนุญำตใหช้นิดของ
ขอ้มลูเป็นประเภทเดียวกนั โดยไมจ่ ำเป็นตอ้งเป็นชนิดเดียวกนั เช่น VARCHAR(45) กบั
CHAR(10) หรือ INT กบั SMALLINT สำมำรถท ำค ำสัง่ SET ได้
2
RELATIONAL SET OPERATORS: UNION
ค ำสัง่ UNION จะใชส้ ำหรบักำรรวมขอ้มูลจำก 2 ตำรำง ใหอ้ยูใ่นตำรำงเดียวกนัโดยขอ้มลูท่ีซ ้ำ
กนัในทั้ง 2 ตำรำงจะตอ้งถูกบนัทึกเพียงแถวเดียว
ตวัอยำ่ง บริษัท ABC ไดซ้ื้อกิจกำรของบริษัท XYZ โดยท่ีบริษัท ABC ตอ้งกำรรวมรำยช่ือลูกคำ้
ของบริษัท ABC เขำ้กบั บริษัท XYZ ซ่ึงมีควำมเป็นไปไดว้ำ่ลูกคำ้ของทั้ง 2 บรษิัทจะเป็นลูกคำ้
รำยเดียวกนั ดงัน้ันกำรรวมรำยช่ือลูกคำ้ใหเ้หลือเพียงตำรำงเดียวน้ัน จะตอ้งมัน่ใจวำ่ขอ้มลู
ลูกคำ้ท่ีซ ้ำกนัจะถูกรวมเป็นแถวเดียว
SELECT CUS_NAME, CUS_EMAIL, CUS_PHONENO FROM ABC.CUSTOMERS
UNION
SELECT CUS_NAME, CUS_EMAIL, CUS_PHONENO FROM XYZ.CUSTOMERS;
3
RELATIONAL SET OPERATORS: INTERSECT
ค ำสัง่ INTERSECT จะใชส้ ำหรบักำรเลือกขอ้มูลท่ีซ ้ำกนัในทั้ง 2 ตำรำง ซ่ึงจะตอ้งแสดงขอ้มลู
เพียงแถวเดียว
ตวัอยำ่ง บริษัท ABC ตอ้งกำรทรำบวำ่ มีลูกคำ้รำยใดบำ้ง ท่ีซ ้ำกบัขอ้มลูลกูคำ้ของบริษัท XYZ
SELECT CUS_NAME, CUS_EMAIL, CUS_PHONENO FROM ABC.CUSTOMERS
INTERSECT
SELECT CUS_NAME, CUS_EMAIL, CUS_PHONENO FROM XYZ.CUSTOMERS;
4
RELATIONAL SET OPERATORS: MINUS
ค ำสัง่ MINUS จะใชส้ ำหรบักำรเลือกขอ้มูลท่ีมีอยูใ่นตำรำงท่ี 1 แต่ไมม่ีในตำรำงท่ี 2
ตวัอยำ่ง บริษัท ABC ตอ้งกำรทรำบวำ่ มีลูกคำ้รำยใดบำ้งของบริษัท ABC ท่ีไมซ่ ้ำกบัขอ้มลู
ลูกคำ้ของบริษัท XYZ
SELECT CUS_NAME, CUS_EMAIL, CUS_PHONENO FROM ABC.CUSTOMERS
MINUS
SELECT CUS_NAME, CUS_EMAIL, CUS_PHONENO FROM XYZ.CUSTOMERS;
5
SYNTAX ALTERNATIVES
หำกระบบจดักำรฐำนขอ้มลูไมส่นับสนุนค ำสัง่ INTERSECT และ MINUS สำมำรถใชค้ ำสัง่ IN
หรือ NOT IN มำใชง้ำนรว่มกบัค ำสัง่ SQL ได ้เช่น
INTERSECT
SELECT CUS_NAME, CUS_EMAIL, CUS_PHONENO FROM ABC.CUSTOMERS
WHERE CUS_EMAIL IN (SELECT DISTINCT CUS_EMAIL
FROM XYZ.CUSTOMERS);
MINUS
SELECT CUS_NAME, CUS_EMAIL, CUS_PHONENO FROM ABC.CUSTOMERS
WHERE CUS_EMAIL NOT IN (SELECT DISTINCT CUS_EMAIL
FROM XYZ.CUSTOMERS);
6
SQL JOIN OPERATORS
เป็นกำรเลือกขอ้มูลจำกหลำยตำรำงเพื่อมำแสดงผลหรือประมวลผลรวมกนั โดยรูปแบบของ
กำรเรียกขอ้มลูรว่มกบัตำรำงอ่ืน ๆ ตำมมำตรฐำน SQL:1999 มีดงัน้ี
INNER JOINS
OUTER JOINS
LEFT OUTER JOIN
RIGHT OUTER JOIN
FULL OUTER JOIN
CROSS JOINS
SQL JOIN OPERATORS
INNER JOINS
คือกำรเช่ือม 2 ตำรำงท่ีมีค่ำเหมือนกนั โดยผลลพัธคื์อแถวขอ้มลูท่ีมีค่ำเหมือนกนัใน 2
ตำรำง โดยใชคี้ยน์อกเป็นตวัเช่ือมระหวำ่งทั้ง 2 ตำรำง เช่น ตำรำง Customer ตอ้งกำร
เช่ือมโยงกบัตำรำง Orders จะใชร้หสัลูกคำ้เป็นตวัเช่ือมขอ้มลูท่ีเหมือนกนั
Customer.customerID = Orders.customerID
ตวัอยำ่งกำร INNER JOIN ระหวำ่งตำรำง Customer กบั Orders
SELECT custName, telephone, COUNT(orderID) AS CountOrder
FROM Customer INNER JOIN Orders ON Customer.customerID = Orders.customerID
WHERE address LIKE '%เชยีงใหม%่'
GROUP BY custName, telephone
HAVING COUNT(orderID) > 10
ORDER BY COUNT(orderID) DESC, custName;
INNER JOINS
เลือกแสดงเลขท่ีใบสัง่ซ้ือ รหสัสินคำ้ ช่ือสินคำ้ รำคำต่อหน่วย จ ำนวน และรำคำรวม เฉพำะใบ
รำยกำรสัง่ซ้ือหมำยเลข 120 เรียงล ำดบัตำมช่ือสินคำ้
SELECT orderID, Products.productID, productName, unitPrice, quantity,
(unitPrice * quantity) AS total
FROM Orders_Line INNER JOIN Products ON Orders_Line.productID = Products.productID
WHERE orderID = 120
ORDER BY productName;
INNER JOINS
เลือกแสดงช่ือลูกคำ้ เลขท่ีใบสัง่ซ้ือ วนัท่ีสัง่ซ้ือ และรำคำรวม เฉพำะใบรำยกำรสัง่ซ้ือของปี
2550 โดยเรียงล ำดบัตำมช่ือลูกคำ้ และวนัท่ีสัง่ซ้ือ
SELECT custName, orders.orderID, orderDate, SUM(unitPrice * quantity) AS total
FROM (((Customer INNER JOIN Orders ON Customer.customerID = Orders.customerID)
INNER JOIN Orders_Line ON Orders.orderID = Orders_Line.orderID)
INNER JOIN Products ON Orders_Line.productID = Products.productID)
WHERE Year(orderDate) = '2550'
GROUP BY custName, orders.orderID, orderDate
ORDER BY custName, orderDate;
INNER JOINS
กำรเช่ือมโยงตำรำงเดิม (Self JOIN) โดยกำรใชน้ำมแฝงของตำรำงเขำ้มำช่วยในกำรเช่ือมต่อ
กลบัมำท่ีตำรำงเดิม เช่น พนักงำนแต่ละคนจะมีหวัหน้ำในกำรควบคุม โดยจะมี headEmp_id
เป็นคอลมัน์ท่ีระบุรหสัพนักงำนท่ีเป็นหวัหน้ำ ซ่ึงพนักงำนบำงคนอำจจะไม่มีหวัหน้ำควบคุมก็
ได ้ดงัตำรำงต่อไปน้ี
SELECT e1.emp_id, e1.emp_name, e1.headEmp_id, e2.emp_name
FROM Employee e1 INNER JOIN Employee e2 ON e1.headEmp_id = e2.emp_id;
OUTER JOINS
กำรเช่ือมโยงระหว่ำงสองตำรำงท่ีคืนค่ำผลลัพธ์แถวท่ีตรงกันและแถวท่ีไม่ตรงของตำรำง
ทำงดำ้นซำ้ย หรือ ขวำ เรียกวำ่ LEFT หรือ RIGHT OUTER JOIN ส่วนกำรเช่ือมโยงท่ีไดผ้ลลพัธ์
ของทั้งหมด คือ ทั้งแถวท่ีตรงกันและไม่ตรงกันทั้งตำรำงดำ้นซำ้ยและขวำ เรียกว่ำ FULL
OUTER JOIN
LEFT OUTER JOIN คืนค่ำขอ้มลูตำรำงดำ้นซำ้ยทั้งหมดท่ีตรงและไมต่รงกบัตำรำงดำ้นขวำ
RIGHT OUTER JOIN คืนค่ำคลำ้ยกบั LEFT OUTER JOIN แต่เป็นมุมมองดำ้นขวำทั้งหมด
FULL OUTER JOIN ผลลพัธท่ี์ไดคื้อกำรน ำผลลพัธข์อง LEFT OUTER JOIN รวมกบั RIGHT
OUTER JOIN
LEFT OUTER JOIN
หำกตอ้งกำรแสดงขอ้มูลลูกคำ้ทั้งหมดและวันท่ีสัง่ซ้ือ โดยคนท่ีไม่มีกำรสั ่งซ้ือก็ต้องกำร
แสดงผลดว้ย
ผลลพัธท่ี์ไดคื้อ
SELECT custName, telephone, orderid, orderDate
FROM Customer LEFT JOIN Orders ON Customer.customertID = Orders.customerID
ORDER BY custName;
custName telephone orderid orderDate
สายัณห ์อุน่นันกาศ 053-873530 103 10/03/2551
นพรัตน ์สรอ้ยโพธิพ์ันธ์ 02-1234567 104 11/03/2551
… … … …
อรรถพล ชตูกินัฑ์ 02-2223456 null null
อรรถพล ไมเ่คย
สัง่ซ้ือสินคำ้
RIGHT OUTER JOIN
ไดผ้ลลพัธแ์บบเดียวกนักบั LEFT OUTER JOIN เพียงแค่สลบัดำ้นของตำรำง
SELECT custName, telephone, orderid, orderDate
FROM Orders RIGHT JOIN Customer
ON Customer.customertID = Orders.customerID
ORDER BY custName;
SELECT custName, telephone, orderid, orderDate
FROM Customer LEFT JOIN Orders
ON Customer.customertID = Orders.customerID
ORDER BY custName;
FULL OUTER JOIN
ผลลพัธท่ี์ไดคื้อกำรน ำผลลพัธข์อง LEFT OUTER JOIN รวมกบั RIGHT OUTER JOIN เช่น
ผลลพัธท่ี์ไดคื้อ
ลูกคำ้ท่ีมีกำรสัง่ซ้ือ
ลูกคำ้ท่ีไมม่ีกำรสัง่ซ้ือ
รำยกำรสัง่ซ้ือท่ีไม่ระบุลูกคำ้
SELECT custName, telephone, orderid, orderDate
FROM Orders FULL OUTER JOIN Customer
ON Customer.customertID = Orders.customerID
ORDER BY custName;
CROSS JOINS
กำร CROSS JOIN คือผลลพัธท่ี์ไดจ้ำกกำรคูณกนัระหวำ่งสองตำรำง ซ่ึงบำงครั้งถูกเรียกว่ำ
Cartesian Product เช่นกนั หำกตอ้งกำรขอ้มลูลูกคำ้ทุกคนคูณกบัสินคำ้ทุกรำยกำร
SELECT custName, productName FROM Customer, Products;
หรอื
SELECT custName, productName FROM Customer CROSS JOIN Products;
custName productName
สายัณห ์อุน่นันกาศ ผา้มา่น
สายัณห ์อุน่นันกาศ ปลอกหมอน
สายัณห ์อุน่นันกาศ หมอนขา้ง
นพรัตน ์สรอ้ยโพธิพั์นธ์ ผา้มา่น
นพรัตน ์สรอ้ยโพธิพั์นธ์ ปลอกหมอน
นพรัตน ์สรอ้ยโพธิพั์นธ์ หมอนขา้ง
อรรถพล ชตูกิันฑ์ ผา้มา่น
อรรถพล ชตูกิันฑ์ ปลอกหมอน
อรรถพล ชตูกิันฑ์ หมอนขา้ง
customerID
custName
1 สายัณห ์อุน่นันกาศ
2 นพรัตน ์สรอ้ยโพธิพั์นธ์
3 อรรถพล ชตูกิันฑ์
productID
productName
1 ผา้มา่น
2 ปลอกหมอน
3 หมอนขา้ง
x =
กำรสอบถำมขอ้มูลแบบซอ้นกัน (NESTED QUERY)
เป็นกำรสรำ้งแบบสอบถำมข้อมูลด้วยค ำสัง่ SELECT แบบซ้อนกันหลำย ๆ ชั้น โดยจะ
ประกอบดว้ยส่วนของชุดค ำสัง่หลกั และค ำสัง่ยอ่ย
กำรสรำ้งค ำสัง่ย่อยโดยคืนค่ำเพียงขอ้มูลเดียว เช่น ตอ้งกำรหำสินคำ้ท่ีมียอดกำรสัง่ซ้ือมำก
ท่ีสุดในแต่ละใบสัง่ซ้ือ
SELECT orderid, Products.productID, productName, quantity
FROM Orders_Line INNER JOIN Products ON Orders_Line.productId = Products.productID
WHERE quantity = (SELECT MAX(quantity) FROM Orders_Line);
กำรสอบถำมขอ้มูลแบบซอ้นกัน (NESTED QUERY)
กำรสรำ้งค ำสัง่ย่อยโดยคืนค่ำหลำย ๆ ขอ้มูล เช่น ตอ้งกำรนับจ ำนวนใบสัง่ซ้ือ และจ ำนวน
สินคำ้ทั้งหมด เฉพำะใบสัง่ซ้ือท่ีมีสินคำ้ท่ีขึ้ นตน้ดว้ยค ำวำ่ “หมอน” เท่ำน้ัน
SELECT Products.productID, productName, count(ordered) AS cntOrd,
sum(quantity) AS sumQty
FROM Orders_Line INNER JOIN Products ON Orders_Line.productId = Products.productID
WHERE Products.productID IN (SELECT productID FROM Products
WHERE productName LIKE 'หมอน%')
GROUP BY Products.productID, productName;
EXAMPLE-1
จงแสดงช่ือลูกคำ้ เลขท่ีใบสัง่ซ้ือ วนัท่ีสัง่ซ้ือ เฉพำะลูกคำ้ท่ีมำสัง่ซ้ือในเดือนมีนำคม 2558
20
EXAMPLE-2
จงแสดงช่ือลูกคำ้ เลขท่ีใบสัง่ซ้ือ วนัท่ีสัง่ซ้ือ ช่ือสินคำ้ และจ ำนวนสินคำ้ เฉพำะลูกคำ้ท่ีมำ
สัง่ซ้ือสินคำ้มำกกวำ่ 100 ช้ิน
21
EXAMPLE-3
จงแสดงรำยช่ือสินคำ้ จ ำนวนใบสัง่ซ้ือ ในช่วงวนัท่ี 1-15 มีนำคม 2558 เฉพำะท่ีมีจ ำนวน
สินคำ้มำกกวำ่ 200 ชิ้ นโดยเรียงล ำดบัจำกจ ำนวนสินคำ้จำกมำกไปหำน้อย หำกจ ำนวนสินคำ้
เท่ำกนัใหเ้รียงล ำดบัจำกชื่อสินคำ้
22
EXAMPLE-4
จงแสดงรหสัสินคำ้ ชื่อสินคำ้ จ ำนวนท่ีสัง่ซ้ือ และ รำคำต่อหน่วย ของใบสัง่ซ้ือหมำยเลข
001/2558
23