/* -- 逻辑查询处理的步骤序号 (5) SELECT (5-2)DISTINCT (5-2) TOP (top_specification) (5-1)<select_list> (1) FROM (1-J) <left_table> <join-type> JOIN <right-table> ON <on_predicate> |(1-A) <left_table> <apply-type> APPLY <right-table_expression> AS <alias> |(1-P) <left_table> PIVOT(<pivot_specification>) AS <alias> |(1-U) <left_table> UNPIVOT(<unpivot_specification>) AS <alias> (2) WHERE (where_precidate) (3) GROUP BY <group_by_specification> (4) HAVING <having_predicate> (6) ORDER BY <order_by_list> */ /* 每一步都会生成一个虚拟表,该虚拟表作为下一步的输入,这些虚拟表对于调用者是不可用的, 只有最后一步生成的虚拟表才会返回给调用者,如果在查询中没有指定某一个子句,最会跳过相应的步骤 */
SET NOCOUNT ON; USE tempdb; IF OBJECT_ID('dbo.Orders') IS NOT NULL DROP TABLE dbo.Orders; IF OBJECT_ID('dbo.Customers') IS NOT NULL DROP TABLE dbo.Customers; GO CREATE TABLE dbo.Customers ( customerid CHAR(5) NOT NULL PRIMARY KEY, city VARCHAR(10) NOT NULL ); CREATE TABLE dbo.Orders ( orderid INT NOT NULL PRIMARY KEY, customerid CHAR(5) NULL REFERENCES Customers(customerid) ); GO INSERT INTO dbo.Customers(customerid, city) VALUES('FISSA', 'Madrid'); INSERT INTO dbo.Customers(customerid, city) VALUES('FRNDO', 'Madrid'); INSERT INTO dbo.Customers(customerid, city) VALUES('KRLOS', 'Madrid'); INSERT INTO dbo.Customers(customerid, city) VALUES('MRPHS', 'Zion'); INSERT INTO dbo.Orders(orderid, customerid) VALUES(1, 'FRNDO'); INSERT INTO dbo.Orders(orderid, customerid) VALUES(2, 'FRNDO'); INSERT INTO dbo.Orders(orderid, customerid) VALUES(3, 'KRLOS'); INSERT INTO dbo.Orders(orderid, customerid) VALUES(4, 'KRLOS'); INSERT INTO dbo.Orders(orderid, customerid) VALUES(5, 'KRLOS'); INSERT INTO dbo.Orders(orderid, customerid) VALUES(6, 'MRPHS'); INSERT INTO dbo.Orders(orderid, customerid) VALUES(7, NULL); SELECT * FROM dbo.Customers; SELECT * FROM dbo.Orders; -- Listing 1-2: Query: Madrid customers with Fewer than three orders -- The query returns customers from Madrid who placed fewer than -- three orders (including zero), and their order count. -- The result is sorted by the order count. SELECT C.customerid, COUNT(O.orderid) AS numorders FROM dbo.Customers AS C LEFT OUTER JOIN dbo.Orders AS O ON C.customerid = O.customerid WHERE C.city = 'Madrid' GROUP BY C.customerid HAVING COUNT(O.orderid) < 3 ORDER BY numorders;