Cộng đồng chia sẻ tri thức Lib24.vn

SQLServerCh06

8a621709196fe872c3309c955660d1f0
Gửi bởi: Khoa CNTT - HCEM 24 tháng 2 2021 lúc 9:18:02 | Được cập nhật: 9 giờ trước (9:56:52) Kiểu file: PPTX | Lượt xem: 100 | Lượt Download: 1 | File size: 1.447413 Mb

Nội dung tài liệu

Tải xuống
Link tài liệu:
Tải xuống

Các tài liệu liên quan


Có thể bạn quan tâm


Thông tin tài liệu

Chapter 6 How to code subqueries Murach's SQL Server 2012, C6 © 2012, Mike Murach & Associates, Inc. Slide 1 Objectives Applied  Code SELECT statements that require subqueries.  Code SELECT statements that use common table expressions (CTEs) to define the subqueries. Knowledge  Describe the way subqueries can be used in the WHERE, HAVING, FROM and SELECT clauses of a SELECT statement.  Describe the difference between a correlated subquery and a noncorrelated subquery.  Describe the use of common table expressions (CTEs). Murach's SQL Server 2012, C6 © 2012, Mike Murach & Associates, Inc. Slide 2 Four ways to introduce a subquery in a SELECT statement 1. 2. 3. 4. In a WHERE clause as a search condition In a HAVING clause as a search condition In the FROM clause as a table specification In the SELECT clause as a column specification Murach's SQL Server 2012, C6 © 2012, Mike Murach & Associates, Inc. Slide 3 A subquery in the WHERE clause SELECT InvoiceNumber, InvoiceDate, InvoiceTotal FROM Invoices WHERE InvoiceTotal > (SELECT AVG(InvoiceTotal) FROM Invoices) ORDER BY InvoiceTotal; The value returned by the subquery 1879.7413 The result set (21 rows) Murach's SQL Server 2012, C6 © 2012, Mike Murach & Associates, Inc. Slide 4 Where a subquery can be introduced If a subquery returns… A single value It can be introduced… Anywhere an expression is allowed A result set with a single column In place of a list of values A result set with one or more columns In place of a table in the FROM clause Murach's SQL Server 2012, C6 © 2012, Mike Murach & Associates, Inc. Slide 5 A query that uses an inner join SELECT InvoiceNumber, InvoiceDate, InvoiceTotal FROM Invoices JOIN Vendors ON Invoices.VendorID = Vendors.VendorID WHERE VendorState = 'CA' ORDER BY InvoiceDate; The result set (40 rows) Murach's SQL Server 2012, C6 © 2012, Mike Murach & Associates, Inc. Slide 6 The same query restated with a subquery SELECT InvoiceNumber, InvoiceDate, InvoiceTotal FROM Invoices WHERE VendorID IN (SELECT VendorID FROM Vendors WHERE VendorState = 'CA') ORDER BY InvoiceDate; The same result set (40 rows) Murach's SQL Server 2012, C6 © 2012, Mike Murach & Associates, Inc. Slide 7 Advantages of joins  The result of a join operation can include columns from both tables.  A join tends to be more intuitive when it uses an existing relationship between two tables.  A query with a join typically performs faster than the same query with a subquery. Advantages of subqueries  A subquery can pass an aggregate value to the outer query.  A subquery tends to be more intuitive when it uses an ad hoc relationship between two tables.  Long, complex queries can sometimes be easier to code using subqueries. Murach's SQL Server 2012, C6 © 2012, Mike Murach & Associates, Inc. Slide 8 The syntax of a WHERE clause that uses an IN phrase with a subquery WHERE test_expression [NOT] IN (subquery) A query that returns vendors without invoices SELECT VendorID, VendorName, VendorState FROM Vendors WHERE VendorID NOT IN (SELECT DISTINCT VendorID FROM Invoices); Murach's SQL Server 2012, C6 © 2012, Mike Murach & Associates, Inc. Slide 9 The result of the subquery (34 rows) The result set (88 rows) Murach's SQL Server 2012, C6 © 2012, Mike Murach & Associates, Inc. Slide 10 The query restated without a subquery SELECT Vendors.VendorID, VendorName, VendorState FROM Vendors LEFT JOIN Invoices ON Vendors.VendorID = Invoices.VendorID WHERE Invoices.VendorID IS NULL; The same result set (88 rows) Murach's SQL Server 2012, C6 © 2012, Mike Murach & Associates, Inc. Slide 11 The syntax of a WHERE clause that uses a comparison operator WHERE expression comparison_operator [SOME|ANY|ALL] (subquery) A query with a subquery in the WHERE condition SELECT InvoiceNumber, InvoiceDate, InvoiceTotal, InvoiceTotal - PaymentTotal - CreditTotal AS BalanceDue FROM Invoices WHERE InvoiceTotal - PaymentTotal - CreditTotal > 0 AND InvoiceTotal - PaymentTotal - CreditTotal < (SELECT AVG(InvoiceTotal - PaymentTotal - CreditTotal) FROM Invoices WHERE InvoiceTotal - PaymentTotal - CreditTotal > 0) ORDER BY InvoiceTotal DESC; Murach's SQL Server 2012, C6 © 2012, Mike Murach & Associates, Inc. Slide 12 The value returned by the subquery 2910.9472 The result set (9 rows) Murach's SQL Server 2012, C6 © 2012, Mike Murach & Associates, Inc. Slide 13 How the ALL keyword works Condition Equivalent expression x x x x x > 2 x < 1 (x = 1) AND (x = 2) (x
1) AND (x
2) > ALL (1, 2) < ALL (1, 2) = ALL (1, 2)
ALL (1, 2) Murach's SQL Server 2012, C6 © 2012, Mike Murach & Associates, Inc. Slide 14 A query that uses the ALL keyword SELECT VendorName, InvoiceNumber, InvoiceTotal FROM Invoices JOIN Vendors ON Invoices.VendorID = Vendors.VendorID WHERE InvoiceTotal > ALL (SELECT InvoiceTotal FROM Invoices WHERE VendorID = 34) ORDER BY VendorName; Murach's SQL Server 2012, C6 © 2012, Mike Murach & Associates, Inc. Slide 15 The result of the subquery The result set (25 rows) Murach's SQL Server 2012, C6 © 2012, Mike Murach & Associates, Inc. Slide 16 How the ANY and SOME keywords work Condition Equivalent expression x x x x x > 1 x < 2 (x = 1) OR (x = 2) (x
1) OR (x
2) > ANY (1, 2) < ANY (1, 2) = ANY (1, 2)
ANY (1, 2) Murach's SQL Server 2012, C6 © 2012, Mike Murach & Associates, Inc. Slide 17 A query that uses the ANY keyword SELECT VendorName, InvoiceNumber, InvoiceTotal FROM Vendors JOIN Invoices ON Vendors.VendorID = Invoices.VendorID WHERE InvoiceTotal < ANY (SELECT InvoiceTotal FROM Invoices WHERE VendorID = 115); Murach's SQL Server 2012, C6 © 2012, Mike Murach & Associates, Inc. Slide 18 The result of the subquery The result set (17 rows) Murach's SQL Server 2012, C6 © 2012, Mike Murach & Associates, Inc. Slide 19 A query that uses a correlated subquery SELECT VendorID, InvoiceNumber, InvoiceTotal FROM Invoices AS Inv_Main WHERE InvoiceTotal > (SELECT AVG(InvoiceTotal) FROM Invoices AS Inv_Sub WHERE Inv_Sub.VendorID = Inv_Main.VendorID) ORDER BY VendorID, InvoiceTotal; The value returned by the subquery for vendor 95 28.5016 The result set (36 rows) Murach's SQL Server 2012, C6 © 2012, Mike Murach & Associates, Inc. Slide 20 Terms  Subquery  Subquery predicate  Correlated subquery  Noncorrelated subquery  Correlation name  Derived table Murach's SQL Server 2012, C6 © 2012, Mike Murach & Associates, Inc. Slide 21 The syntax of a subquery with EXISTS WHERE [NOT] EXISTS (subquery) A query that returns vendors without invoices SELECT VendorID, VendorName, VendorState FROM Vendors WHERE NOT EXISTS (SELECT * FROM Invoices WHERE Invoices.VendorID = Vendors.VendorID); The result set (88 rows) Murach's SQL Server 2012, C6 © 2012, Mike Murach & Associates, Inc. Slide 22 A subquery coded in the FROM clause SELECT Invoices.VendorID, MAX(InvoiceDate) AS LatestInv, AVG(InvoiceTotal) AS AvgInvoice FROM Invoices JOIN (SELECT TOP 5 VendorID, AVG(InvoiceTotal) AS AvgInvoice FROM Invoices GROUP BY VendorID ORDER BY AvgInvoice DESC) AS TopVendor ON Invoices.VendorID = TopVendor.VendorID GROUP BY Invoices.VendorID ORDER BY LatestInv DESC; Murach's SQL Server 2012, C6 © 2012, Mike Murach & Associates, Inc. Slide 23 The derived table generated by the subquery The result set Murach's SQL Server 2012, C6 © 2012, Mike Murach & Associates, Inc. Slide 24 A correlated subquery in the SELECT clause SELECT DISTINCT VendorName, (SELECT MAX(InvoiceDate) FROM Invoices WHERE Invoices.VendorID = Vendors.VendorID) AS LatestInv FROM Vendors ORDER BY LatestInv DESC; The result set (122 rows) Murach's SQL Server 2012, C6 © 2012, Mike Murach & Associates, Inc. Slide 25 The same query restated using a join SELECT VendorName, MAX(InvoiceDate) AS LatestInv FROM Vendors LEFT JOIN Invoices ON Vendors.VendorID = Invoices.VendorID GROUP BY VendorName ORDER BY LatestInv DESC; The same result set (122 rows) Murach's SQL Server 2012, C6 © 2012, Mike Murach & Associates, Inc. Slide 26 A complex query that uses three subqueries SELECT Summary1.VendorState, Summary1.VendorName, TopInState.SumOfInvoices FROM (SELECT V_Sub.VendorState, V_Sub.VendorName, SUM(I_Sub.InvoiceTotal) AS SumOfInvoices FROM Invoices AS I_Sub JOIN Vendors AS V_Sub ON I_Sub.VendorID = V_Sub.VendorID GROUP BY V_Sub.VendorState, V_Sub.VendorName) AS Summary1 Murach's SQL Server 2012, C6 © 2012, Mike Murach & Associates, Inc. Slide 27 A complex query (continued) JOIN (SELECT Summary2.VendorState, MAX(Summary2.SumOfInvoices) AS SumOfInvoices FROM (SELECT V_Sub.VendorState, V_Sub.VendorName, SUM(I_Sub.InvoiceTotal) AS SumOfInvoices FROM Invoices AS I_Sub JOIN Vendors AS V_Sub ON I_Sub.VendorID = V_Sub.VendorID GROUP BY V_Sub.VendorState, V_Sub.VendorName) AS Summary2 GROUP BY Summary2.VendorState) AS TopInState ON Summary1.VendorState = TopInState.VendorState AND Summary1.SumOfInvoices = TopInState.SumOfInvoices ORDER BY Summary1.VendorState; Murach's SQL Server 2012, C6 © 2012, Mike Murach & Associates, Inc. Slide 28 The result set (10 rows) Murach's SQL Server 2012, C6 © 2012, Mike Murach & Associates, Inc. Slide 29 A procedure for building complex queries 1. 2. 3. 4. State the problem to be solved by the query in English. Use pseudocode to outline the query. If necessary, use pseudocode to outline each subquery. Code the subqueries and test them to be sure that they return the correct data. 5. Code and test the final query. Murach's SQL Server 2012, C6 © 2012, Mike Murach & Associates, Inc. Slide 30 Pseudocode for the query SELECT Summary1.VendorState, Summary1.VendorName, TopInState.SumOfInvoices FROM (Derived table returning VendorState, VendorName, SumOfInvoices) AS Summary1 JOIN (Derived table returning VendorState, MAX(SumOfInvoices)) AS TopInState ON Summary1.VendorState = TopInState.VendorState AND Summary1.SumOfInvoices = TopInState.SumOfInvoices ORDER BY Summary1.VendorState; Murach's SQL Server 2012, C6 © 2012, Mike Murach & Associates, Inc. Slide 31 The code for the Summary1 and Summary2 subqueries SELECT V_Sub.VendorState, V_Sub.VendorName, SUM(I_Sub.InvoiceTotal) AS SumOfInvoices FROM Invoices AS I_Sub JOIN Vendors AS V_Sub ON I_Sub.VendorID = V_Sub.VendorID GROUP BY V_Sub.VendorState, V_Sub.VendorName; The result of the Summary1 and Summary2 subqueries (34 rows) Murach's SQL Server 2012, C6 © 2012, Mike Murach & Associates, Inc. Slide 32 Pseudocode for the TopInState subquery SELECT Summary2.VendorState, MAX(Summary2.SumOfInvoices) FROM (Derived table returning VendorState, VendorName, SumOfInvoices) AS Summary2 GROUP BY Summary2.VendorState; The result of the TopInState subquery (10 rows) Murach's SQL Server 2012, C6 © 2012, Mike Murach & Associates, Inc. Slide 33 The syntax of a CTE WITH cte_name1 AS (query_definition1) [, cte_name2 AS (query_definition2)] [...] sql_statement Murach's SQL Server 2012, C6 © 2012, Mike Murach & Associates, Inc. Slide 34 Two CTEs and a query that uses them WITH Summary AS ( SELECT VendorState, VendorName, SUM(InvoiceTotal) AS SumOfInvoices FROM Invoices JOIN Vendors ON Invoices.VendorID = Vendors.VendorID GROUP BY VendorState, VendorName ), TopInState AS ( SELECT VendorState, MAX(SumOfInvoices) AS SumOfInvoices FROM Summary GROUP BY VendorState ) SELECT Summary.VendorState, Summary.VendorName, TopInState.SumOfInvoices FROM Summary JOIN TopInState ON Summary.VendorState = TopInState.VendorState AND Summary.SumOfInvoices = TopInState.SumOfInvoices ORDER BY Summary.VendorState; Murach's SQL Server 2012, C6 © 2012, Mike Murach & Associates, Inc. Slide 35 The result set (10 rows) Murach's SQL Server 2012, C6 © 2012, Mike Murach & Associates, Inc. Slide 36 The Employees table Murach's SQL Server 2012, C6 © 2012, Mike Murach & Associates, Inc. Slide 37 A recursive CTE that returns hierarchical data WITH EmployeesCTE AS ( -- Anchor member SELECT EmployeeID, FirstName + ' ' + LastName As EmployeeName, 1 As Rank FROM Employees WHERE ManagerID IS NULL UNION ALL -- Recursive member SELECT Employees.EmployeeID, FirstName + ' ' + LastName, Rank + 1 FROM Employees JOIN EmployeesCTE ON Employees.ManagerID = EmployeesCTE.EmployeeID ) SELECT * FROM EmployeesCTE ORDER BY Rank, EmployeeID; Murach's SQL Server 2012, C6 © 2012, Mike Murach & Associates, Inc. Slide 38 The final result set Murach's SQL Server 2012, C6 © 2012, Mike Murach & Associates, Inc. Slide 39 Terms  Common table expression (CTE)  Recursive query  Recursive CTE Murach's SQL Server 2012, C6 © 2012, Mike Murach & Associates, Inc. Slide 40