筆記-Microsoft SQL Server 2008技術內幕:T-SQL語言基礎-05 表表達式

通常來講,表表達式既不會對性能產生正面影響,也不會對性能產生負面影響。express

注意下面這種代碼風格:模塊化

SELECT orderyear, COUNT(DISTINCT custid) AS numcusts
FROM (SELECT YEAR(orderdate), custid
      FROM Sales.Orders) AS D(orderyear, custid)
GROUP BY orderyear;

公用表表達式

公用表表達式(CTE,Common table expression)是用WITH子句定義的,通常格式爲:函數

WITH USACusts AS
(
  SELECT custid, companyname
  FROM Sales.Customers
  WHERE country = N'USA'
)
SELECT * FROM USACusts;

 和派生表同樣,一旦外部查詢完成,CTE的生命期就結束了。post

CTE分配列別名的方式——內聯格式和外部格式,內聯格式:性能

WITH C AS
(
  SELECT YEAR(orderdate) AS orderyear, custid
  FROM Sales.Orders
)
SELECT orderyear, COUNT(DISTINCT custid) AS numcusts
FROM C
GROUP BY orderyear;

 外部格式:ui

WITH C(orderyear, custid) AS
(
  SELECT YEAR(orderdate), custid
  FROM Sales.Orders
)
SELECT orderyear, COUNT(DISTINCT custid) AS numcusts
FROM C
GROUP BY orderyear;

 定義多個CTE:spa

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;

 與嵌套的派生表代碼相比,上面這種模塊化的代碼大大提升了代碼的可讀性和可維護性。code

視圖

建立一個視圖:blog

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

 記住一點,在定義表表達式的查詢語句中不容許出現ORDER BY子句,由於關係表之間的行沒有順序。試圖建立一個有序視圖也是不合理的,SQL Server將會報錯。應該在使用視圖的外部查詢中使用ORDER BY子句。ip

內聯表值函數

如下代碼建立一個內聯表值函數:

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

 使用這個函數:

SELECT orderid, custid
FROM dbo.fn_GetCustOrders(1) AS CO;

總結

藉助表表達式能夠簡化代碼,提升代碼的維護性,還能夠封裝查詢邏輯。當須要使用表表達式時,若是是不計劃重用它們的定義,則使用派生表或者CTE;當須要定義可重用的表表達式時,能夠使用視圖和內聯表值函數。

相關文章
相關標籤/搜索