Chapter 05 - Table Expressions
来源:互联网 发布:淘宝店营销策划书范文 编辑:程序博客网 时间:2024/04/28 18:44
---------------------------------------------------------------------
-- Microsoft SQL Server 2008 T-SQL Fundamentals
-- Chapter 5 - Table Expressions
-- ?2008 Itzik Ben-Gan
---------------------------------------------------------------------
---------------------------------------------------------------------
-- Derived Tables
---------------------------------------------------------------------
USE TSQLFundamentals2008;
SELECT *
FROM (SELECT custid, companyname
FROM Sales.Customers
WHERE country = N'USA') AS USACusts;
GO
---------------------------------------------------------------------
-- Assigning Column Aliases
---------------------------------------------------------------------
-- Following fails
SELECT
YEAR(orderdate) AS orderyear,
COUNT(DISTINCT custid) AS numcusts
FROM Sales.Orders
GROUP BY orderyear;
GO
-- Listing 5-1 Query with a Derived Table using Inline Aliasing Form
SELECT orderyear, COUNT(DISTINCT custid) AS numcusts
FROM (SELECT YEAR(orderdate) AS orderyear, custid
FROM Sales.Orders) AS D
GROUP BY orderyear;
SELECT YEAR(orderdate) AS orderyear, COUNT(DISTINCT custid) AS numcusts
FROM Sales.Orders
GROUP BY YEAR(orderdate);
-- External column aliasing
SELECT orderyear, COUNT(DISTINCT custid) AS numcusts
FROM (SELECT YEAR(orderdate), custid
FROM Sales.Orders) AS D(orderyear, custid)
GROUP BY orderyear;
GO
---------------------------------------------------------------------
-- Using Arguments
---------------------------------------------------------------------
-- Yearly Count of Customers handled by Employee 3
DECLARE @empid AS INT = 3;
/*
-- Prior to SQL Server 2008 use separate DECLARE and SET statements:
DECLARE @empid AS INT;
SET @empid = 3;
*/
SELECT orderyear, COUNT(DISTINCT custid) AS numcusts
FROM (SELECT YEAR(orderdate) AS orderyear, custid
FROM Sales.Orders
WHERE empid = @empid) AS D
GROUP BY orderyear;
GO
---------------------------------------------------------------------
-- Nesting
---------------------------------------------------------------------
-- Listing 5-2 Query with Nested Derived Tables
SELECT orderyear, numcusts
FROM (SELECT orderyear, COUNT(DISTINCT custid) AS numcusts
FROM (SELECT YEAR(orderdate) AS orderyear, custid
FROM Sales.Orders) AS D1
GROUP BY orderyear) AS D2
WHERE numcusts > 70;
SELECT YEAR(orderdate) AS orderyear, COUNT(DISTINCT custid) AS numcusts
FROM Sales.Orders
GROUP BY YEAR(orderdate)
HAVING COUNT(DISTINCT custid) > 70;
---------------------------------------------------------------------
-- Multiple References
---------------------------------------------------------------------
-- Listing 5-3 Multiple Derived Tables Based on the Same Query
SELECT Cur.orderyear,
Cur.numcusts AS curnumcusts, Prv.numcusts AS prvnumcusts,
Cur.numcusts - Prv.numcusts AS growth
FROM (SELECT YEAR(orderdate) AS orderyear,
COUNT(DISTINCT custid) AS numcusts
FROM Sales.Orders
GROUP BY YEAR(orderdate)) AS Cur
LEFT OUTER JOIN
(SELECT YEAR(orderdate) AS orderyear,
COUNT(DISTINCT custid) AS numcusts
FROM Sales.Orders
GROUP BY YEAR(orderdate)) AS Prv
ON Cur.orderyear = Prv.orderyear + 1;
---------------------------------------------------------------------
-- Common Table Expressions
---------------------------------------------------------------------
WITH USACusts AS
(
SELECT custid, companyname
FROM Sales.Customers
WHERE country = N'USA'
)
SELECT * FROM USACusts;
---------------------------------------------------------------------
-- Assigning Column Aliases
---------------------------------------------------------------------
-- Inline column aliasing
WITH C AS
(
SELECT YEAR(orderdate) AS orderyear, custid
FROM Sales.Orders
)
SELECT orderyear, COUNT(DISTINCT custid) AS numcusts
FROM C
GROUP BY orderyear;
-- External column aliasing
WITH C(orderyear, custid) AS
(
SELECT YEAR(orderdate), custid
FROM Sales.Orders
)
SELECT orderyear, COUNT(DISTINCT custid) AS numcusts
FROM C
GROUP BY orderyear;
GO
---------------------------------------------------------------------
-- Using Arguments
---------------------------------------------------------------------
DECLARE @empid AS INT = 3;
/*
-- Prior to SQL Server 2008 use separate DECLARE and SET statements:
DECLARE @empid AS INT;
SET @empid = 3;
*/
WITH C AS
(
SELECT YEAR(orderdate) AS orderyear, custid
FROM Sales.Orders
WHERE empid = @empid
)
SELECT orderyear, COUNT(DISTINCT custid) AS numcusts
FROM C
GROUP BY orderyear;
GO
---------------------------------------------------------------------
-- Defining Multiple CTEs
---------------------------------------------------------------------
WITH C1 AS
(
SELECT YEAR(orderdate) AS orderyear, custid
FROM Sales.Orders
),
C2 AS
(
SELECT orderyear, COUNT(DISTINCT custid) AS numcusts
FROM C1
GROUP BY orderyear
)
SELECT orderyear, numcusts
FROM C2
WHERE numcusts > 70;
---------------------------------------------------------------------
-- Multiple References
---------------------------------------------------------------------
WITH YearlyCount AS
(
SELECT YEAR(orderdate) AS orderyear,
COUNT(DISTINCT custid) AS numcusts
FROM Sales.Orders
GROUP BY YEAR(orderdate)
)
SELECT Cur.orderyear,
Cur.numcusts AS curnumcusts, Prv.numcusts AS prvnumcusts,
Cur.numcusts - Prv.numcusts AS growth
FROM YearlyCount AS Cur
LEFT OUTER JOIN YearlyCount AS Prv
ON Cur.orderyear = Prv.orderyear + 1;
---------------------------------------------------------------------
-- Recursive CTEs (Advanced, Optional)
---------------------------------------------------------------------
WITH EmpsCTE AS
(
SELECT empid, mgrid, firstname, lastname
FROM HR.Employees
WHERE empid = 2
UNION ALL
SELECT C.empid, C.mgrid, C.firstname, C.lastname
FROM EmpsCTE AS P
JOIN HR.Employees AS C
ON C.mgrid = P.empid
)
SELECT empid, mgrid, firstname, lastname
FROM EmpsCTE;
---------------------------------------------------------------------
-- Views
---------------------------------------------------------------------
---------------------------------------------------------------------
-- Views Described
---------------------------------------------------------------------
-- Creating VUSACusts View
USE TSQLFundamentals2008;
IF OBJECT_ID('Sales.USACusts') IS NOT NULL
DROP VIEW Sales.USACusts;
GO
CREATE VIEW Sales.USACusts
AS
SELECT
custid, companyname, contactname, contacttitle, address,
city, region, postalcode, country, phone, fax
FROM Sales.Customers
WHERE country = N'USA';
GO
SELECT custid, companyname
FROM Sales.USACusts;
GO
---------------------------------------------------------------------
-- Views and ORDER BY
---------------------------------------------------------------------
-- ORDER BY in a View is not Allowed
ALTER VIEW Sales.USACusts
AS
SELECT
custid, companyname, contactname, contacttitle, address,
city, region, postalcode, country, phone, fax
FROM Sales.Customers
WHERE country = N'USA'
ORDER BY region;
GO
-- Instead, use ORDER BY in Outer Query
SELECT custid, companyname, region
FROM Sales.USACusts
ORDER BY region;
GO
-- Do not Rely on TOP
ALTER VIEW Sales.USACusts
AS
SELECT TOP (100) PERCENT
custid, companyname, contactname, contacttitle, address,
city, region, postalcode, country, phone, fax
FROM Sales.Customers
WHERE country = N'USA'
ORDER BY region;
GO
-- Query USACusts
SELECT custid, companyname, region
FROM Sales.USACusts;
GO
---------------------------------------------------------------------
-- View Options
---------------------------------------------------------------------
---------------------------------------------------------------------
-- ENCRYPTION
---------------------------------------------------------------------
ALTER VIEW Sales.USACusts
AS
SELECT
custid, companyname, contactname, contacttitle, address,
city, region, postalcode, country, phone, fax
FROM Sales.Customers
WHERE country = N'USA';
GO
SELECT OBJECT_DEFINITION(OBJECT_ID('Sales.USACusts'));
GO
ALTER VIEW Sales.USACusts WITH ENCRYPTION
AS
SELECT
custid, companyname, contactname, contacttitle, address,
city, region, postalcode, country, phone, fax
FROM Sales.Customers
WHERE country = N'USA';
GO
SELECT OBJECT_DEFINITION(OBJECT_ID('Sales.USACusts'));
EXEC sp_helptext 'Sales.USACusts';
GO
---------------------------------------------------------------------
-- SCHEMABINDING
---------------------------------------------------------------------
ALTER VIEW Sales.USACusts WITH SCHEMABINDING
AS
SELECT
custid, companyname, contactname, contacttitle, address,
city, region, postalcode, country, phone, fax
FROM Sales.Customers
WHERE country = N'USA';
GO
-- Try a schema change
ALTER TABLE Sales.Customers DROP COLUMN address;
GO
---------------------------------------------------------------------
-- CHECK OPTION
---------------------------------------------------------------------
-- Notice that you can insert a row through the view
INSERT INTO Sales.USACusts(
companyname, contactname, contacttitle, address,
city, region, postalcode, country, phone, fax)
VALUES(
N'Customer ABCDE', N'Contact ABCDE', N'Title ABCDE', N'Address ABCDE',
N'London', NULL, N'12345', N'UK', N'012-3456789', N'012-3456789');
-- But when you query the view, you won't see it
SELECT custid, companyname, country
FROM Sales.USACusts
WHERE companyname = N'Customer ABCDE';
-- You can see it in the table, though
SELECT custid, companyname, country
FROM Sales.Customers
WHERE companyname = N'Customer ABCDE';
GO
-- Add CHECK OPTION to the View
ALTER VIEW Sales.USACusts WITH SCHEMABINDING
AS
SELECT
custid, companyname, contactname, contacttitle, address,
city, region, postalcode, country, phone, fax
FROM Sales.Customers
WHERE country = N'USA'
WITH CHECK OPTION;
GO
-- Notice that you can't insert a row through the view
INSERT INTO Sales.USACusts(
companyname, contactname, contacttitle, address,
city, region, postalcode, country, phone, fax)
VALUES(
N'Customer FGHIJ', N'Contact FGHIJ', N'Title FGHIJ', N'Address FGHIJ',
N'London', NULL, N'12345', N'UK', N'012-3456789', N'012-3456789');
GO
-- Cleanup
DELETE FROM Sales.Customers
WHERE custid > 91;
DBCC CHECKIDENT('Sales.Customers', RESEED, 91);
IF OBJECT_ID('Sales.USACusts') IS NOT NULL DROP VIEW Sales.USACusts;
GO
---------------------------------------------------------------------
-- Inline User Defined Functions
---------------------------------------------------------------------
-- Creating fn_GetCustOrders function
USE TSQLFundamentals2008;
IF OBJECT_ID('dbo.fn_GetCustOrders') IS NOT NULL
DROP FUNCTION dbo.fn_GetCustOrders;
GO
CREATE FUNCTION dbo.fn_GetCustOrders
(@cid AS INT) RETURNS TABLE
AS
RETURN
SELECT orderid, custid, empid, orderdate, requireddate,
shippeddate, shipperid, freight, shipname, shipaddress, shipcity,
shipregion, shippostalcode, shipcountry
FROM Sales.Orders
WHERE custid = @cid;
GO
-- Test Function
SELECT orderid, custid
FROM dbo.fn_GetCustOrders(1) AS CO;
SELECT CO.orderid, CO.custid, OD.productid, OD.qty
FROM dbo.fn_GetCustOrders(1) AS CO
JOIN Sales.OrderDetails AS OD
ON CO.orderid = OD.orderid;
GO
-- Cleanup
IF OBJECT_ID('dbo.fn_GetCustOrders') IS NOT NULL
DROP FUNCTION dbo.fn_GetCustOrders;
GO
---------------------------------------------------------------------
-- APPLY
---------------------------------------------------------------------
SELECT S.shipperid, E.empid
FROM Sales.Shippers AS S
CROSS JOIN HR.Employees AS E;
SELECT S.shipperid, E.empid
FROM Sales.Shippers AS S
CROSS APPLY HR.Employees AS E;
-- 3 most recent orders for each customer
SELECT C.custid, A.orderid, A.orderdate
FROM Sales.Customers AS C
CROSS APPLY
(SELECT TOP(3) orderid, empid, orderdate, requireddate
FROM Sales.Orders AS O
WHERE O.custid = C.custid
ORDER BY orderdate DESC, orderid DESC) AS A;
-- 3 most recent orders for each customer,
-- Include customers without orders
SELECT C.custid, A.orderid, A.orderdate
FROM Sales.Customers AS C
OUTER APPLY
(SELECT TOP(3) orderid, empid, orderdate, requireddate
FROM Sales.Orders AS O
WHERE O.custid = C.custid
ORDER BY orderdate DESC, orderid DESC) AS A;
-- Creation Script for the Function fn_TopOrders
IF OBJECT_ID('dbo.fn_TopOrders') IS NOT NULL
DROP FUNCTION dbo.fn_TopOrders;
GO
CREATE FUNCTION dbo.fn_TopOrders
(@custid AS INT, @n AS INT)
RETURNS TABLE
AS
RETURN
SELECT TOP(@n) orderid, empid, orderdate, requireddate
FROM Sales.Orders
WHERE custid = @custid
ORDER BY orderdate DESC, orderid DESC;
GO
SELECT
C.custid, C.companyname,
A.orderid, A.empid, A.orderdate, A.requireddate
FROM Sales.Customers AS C
CROSS APPLY dbo.fn_TopOrders(C.custid, 3) AS A;
- Chapter 05 - Table Expressions
- Chapter 05 - Table Expressions - Exercises
- Chapter 05 - Table Expressions - Solutions
- [primer]Chapter-5 Expressions
- Chapter 5 Expressions
- chapter 3Expressions
- Chapter 5. Expressions
- Chapter 3 - Variables and Expressions
- Chapter 11 Regular Expressions&Assignment
- Expressions, and Prints-Learning Python-Chapter 11
- 用 CTE (Common Table Expressions) 切割 string
- Chapter 02 - Single-Table Queries
- chapter 20 The Table Library
- Chapter 2 – Types, Operators and Expressions of TCPL
- Chapter 6. Simple HTML Processing with Regular Expressions
- 《AspectC++ Language Reference》chapter 3: Match Expressions & chapter 4: Predefined Pointcut Functions
- Expressions
- Expressions
- Chapter 03 - Joins - Solutions
- 暑假集训总结 -- 持续更新
- Chapter 04 - Subqueries
- Chapter 04 - Subqueries - Exercises
- Chapter 04 - Subqueries - Solutions
- Chapter 05 - Table Expressions
- HDOJ3958期望
- Chapter 05 - Table Expressions - Exercises
- Chapter 05 - Table Expressions - Solutions
- Delphi用IdHTTP提交自定义Cookie
- Chapter 06 - Set Operations
- Chapter 06 - Set Operations - Exercises
- asm基础学习1
- Chapter 06 - Set Operations - Solutions