FROM (Transact-SQL)

更新: 2005 年 12 月 5 日

指定 DELETE、SELECT 及 UPDATE 陳述式中使用的資料表、檢視、衍生資料表及聯結資料表。在 SELECT 陳述式中,除非選取清單只包含常數、變數及算術運算式 (無資料行名稱),否則都需要 FROM 子句。

主題連結圖示Transact-SQL 語法慣例

語法

[ FROM { <table_source> } [ ,...n ] ] 
<table_source> ::= 
{
        table_or_view_name [ [ AS ] table_alias ] [ <tablesample_clause> ] 
        [ WITH ( < table_hint > [ [ , ]...n ] ) ] 
    | rowset_function [ [ AS ] table_alias ] 
        [ ( bulk_column_alias [ ,...n ] ) ] 
        | user_defined_function [ [ AS ] table_alias ] [ (column_alias [ ,...n ] ) ]
    | OPENXML <openxml_clause> 
    | derived_table [ AS ] table_alias [ ( column_alias [ ,...n ] ) ] 
    | <joined_table> 
    | <pivoted_table> 
    | <unpivoted_table>
      | @variable [ [ AS ] table_alias ]
        | @variable.function_call ( expression [ ,...n ] ) [ [ AS ] table_alias ] [ (column_alias [ ,...n ] ) ]
}
<tablesample_clause> ::= 
    TABLESAMPLE [SYSTEM] ( sample_number [ PERCENT | ROWS ] ) 
        [ REPEATABLE ( repeat_seed ) ] 

<joined_table> ::= 
{
    <table_source> <join_type> <table_source> ON <search_condition> 
    | <table_source> CROSS JOIN <table_source> 
    | left_table_source { CROSS | OUTER } APPLY right_table_source 
    | [ ( ] <joined_table> [ ) ] 
}
<join_type> ::= 
    [ { INNER | { { LEFT | RIGHT | FULL } [ OUTER ] } } [ <join_hint> ] ]
    JOIN

<pivoted_table> ::=
        table_source PIVOT <pivot_clause> table_alias

<pivot_clause> ::=
        ( aggregate_function ( value_column ) 
        FOR pivot_column 
        IN ( <column_list> ) 
    ) 

<unpivoted_table> ::=
        table_source UNPIVOT <unpivot_clause> table_alias

<unpivot_clause> ::=
        ( value_column FOR pivot_column IN ( <column_list> ) ) 

<column_list> ::=
          column_name [ ,...n ]

引數

  • <table_source>
    指定 Transact-SQL 陳述式中使用的資料表、檢視或衍生資料表來源 (含有別名或不含別名)。陳述式中最多只能使用 256 個資料表來源 (雖然這項限制會隨著可用記憶體和查詢中之其他運算式的複雜度而改變)。個別查詢可能無法支援多達 256 個資料表來源。table 變數可以指定為資料表來源。

    ms177634.note(zh-tw,SQL.90).gif附註:
    如果查詢中參考大量資料表,則可能會降低查詢效能。編譯和最佳化時間也會受其他因素影響。這些因素包括每個 <table_source> 上是否有索引和索引檢視,以及 SELECT 陳述式中之 <select_list> 的大小。

    FROM 關鍵字後面的資料表來源順序不會影響傳回的結果集。當 FROM 子句中出現重複的名稱時,SQL Server 2005 會傳回錯誤。

  • table_or_view_name
    這是資料表或檢視的名稱。

    如果資料表或檢視存在於執行 SQL Server 之執行個體的相同電腦上之其他資料庫中,請在表單 database.schema.object_name 中使用完整名稱。如果資料表或檢視存在於連結伺服器上之本機伺服器的外部,請在 linked_server.catalog.schema.object 表單中使用四部分的名稱。如果四部分的資料表或檢視名稱是利用 OPENDATASOURCE 函數,建構作為名稱的伺服器部分,則該名稱也可用來指定資料表來源。如需有關該函數的詳細資訊,請參閱<OPENDATASOURCE (Transact-SQL)>。

  • [AS] table_alias
    這是 table_source 的別名,它有兩個用途:方便使用,或用以分辨自我聯結或次查詢中的資料表或檢視。別名通常是一個縮短的資料表名稱,可用來參考聯結中之資料表的特定資料行。如果相同的資料行名稱存在於聯結中的多個資料表中,SQL Server 會要求資料行名稱必須被資料表名稱、檢視名稱或別名所限定。如果已定義別名,就不能使用資料表名稱。

    當使用衍生資料表、資料列集或資料表值函數或運算子子句 (如 PIVOT 或 UNPIVOT) 時,子句尾端所需的 table_alias 是傳回的所有資料行 (包括群組作業資料行) 的關聯資料表名稱。

  • WITH ( <table_hint> )
    指定查詢最佳化工具必須搭配這份資料表,並針對這個陳述式來使用最佳化或鎖定策略。如需詳細資訊,請參閱<資料表提示 (Transact-SQL)>。

    在 SQL Server 2005 中,除了部分例外狀況,只有在利用 WITH 關鍵字來指定提示時,FROM 子句才支援資料表提示。另外,還必須利用括號來指定資料表提示。

    以下是允許和不允許使用 WITH 關鍵字的資料表提示:NOLOCK、READUNCOMMITTED、UPDLOCK、REPEATABLEREAD、SERIALIZABLE、READCOMMITTED、FASTFIRSTROW、TABLOCK、TABLOCKX、PAGLOCK、ROWLOCK、NOWAIT、READPAST、XLOCK 及 NOEXPAND。如果是利用不含 WITH 關鍵字的方式指定這些資料表提示,則必須單獨指定提示。例如:FROM t (fastfirstrow)

    如果是利用含有其他選項的方式指定提示 (例如:在 (fastfirstrow, index(myindex) 中),則必須利用含有 WITH 關鍵字的方式指定提示,例如:

    FROM t WITH (fastfirstrow, index(myindex)).

    如果資料庫的相容性層級為 80 或更早,提示就不一定要使用 WITH 關鍵字。

  • rowset_function
    指定資料列集函數之一 (如 OPENROWSET),利用該函數來傳回可使用的物件,而不是傳回資料表參考。如需有關資料列集函數清單的詳細資訊,請參閱<資料列集函數 (Transact-SQL)>。
  • bulk_column_alias
    這是一個用以取代結果集中之資料行名稱的選擇性別名。資料行別名只能用在搭配 BULK 選項使用 OPENROWSET 函數的 SELECT 陳述式中。當您使用 bulk_column_alias 時,請依照檔案中之資料行所採用的相同順序,指定每個資料表資料行的別名。

    ms177634.note(zh-tw,SQL.90).gif附註:
    這個別名會覆寫 XML 格式檔之 COLUMN 元素中的 NAME 屬性。
  • user_defined_function
    指定資料表值函數。
  • OPENXML <openxml_clause>
    透過 XML 文件提供資料列集的檢視。如需詳細資訊,請參閱<OPENXML (Transact-SQL)>。
  • derived_table
    這是用來從資料庫擷取資料列的次查詢。derived_table 作為對外部查詢的輸入。
  • column_alias
    這是一個用以取代衍生資料表結果集中之資料行名稱的選擇性別名。選取清單中的每個資料行都包含一個資料行別名,且會利用括號包住資料行別名的完整清單。
  • <tablesample_clause>
    指定必須從資料表傳回資料範例。該範例可能只是近似資料。這個子句可用於 SELECT、UPDATE 或 DELETE 陳述式中的任何主要或聯結資料表。TABLESAMPLE 不能利用檢視來指定。如需詳細資訊,請參閱<使用 TABLESAMPLE 限制結果集>。

    ms177634.note(zh-tw,SQL.90).gif附註:
    當您針對升級為 SQL Server 2005 的資料庫使用 TABLESAMPLE 時,資料庫的相容性層級必須設為 90。若要設定資料庫相容性層級,請參閱<sp_dbcmptlevel (Transact-SQL)>。
  • SYSTEM
    這是 ANSI SQL 所指定之依實作方式而定的取樣方法。在 SQL Server 2005 中,這是唯一的可用取樣方法,而且,依預設,會採用這種方法。SYSTEM 採用頁面型取樣方法,這種方法會從資料表中為範例選擇一組隨機頁面,然後將這些頁面上的所有資料列當做範例子集傳回。如需詳細資訊,請參閱<使用 TABLESAMPLE 限制結果集>。
  • sample_number
    這是用以代表資料列之百分比或數目的精確或近似常數數值運算式。當利用 PERCENT 指定時,sample_number 會利用隱含方式轉換為 float 值;否則,它會轉換為 bigint。PERCENT 是預設值。
  • PERCENT
    指定應該從資料表中擷取資料表資料列的 sample_number 百分比。當指定 PERCENT 時,SQL Server 會傳回所指定之百分比的近似值。當指定 PERCENT 時,sample_number 運算式必須評估為從 0 到 100 的值。
  • ROWS
    指定必須擷取近似之資料列的 sample_number。當指定 ROWS 時,SQL Server 會傳回所指定之資料列數的近似值。當指定 ROWS 時,sample_number 運算式必須評估為大於零的整數值。
  • REPEATABLE
    指出所選範例可以重新傳回。當利用相同的 repeat_seed 值指定時,只要資料表中的所有資料列都尚未變更,SQL Server 就會傳回相同的資料列子集。當以不同的 repeat_seed 值指定時,SQL Server 有可能會傳回資料表中資料列的不同取樣。對資料表執行的下列動作均視為變更:插入、更新、刪除、索引重建或重新組織,以及資料庫還原或附加。
  • repeat_seed
    這是 SQL Server 用來產生亂數的一個常數整數運算式。repeat_seedbigint。如果未指定 repeat_seed,SQL Server 會隨機指派一個值。如果是特定的 repeat_seed 值,只要尚未將變更套用至資料表,取樣結果一律相同。repeat_seed 運算式必須評估為大於零的整數。
  • <joined_table>
    這是兩個或兩個以上的資料表所產生的結果集。如果是多個聯結,請利用括號來變更聯結的自然順序。
  • <join_type>
    指定聯結動作的類型。
  • INNER
    指定必須傳回所有相符的資料列配對。捨棄兩份資料表中不相符的資料列。如果未指定聯點類型,這就是預設值。
  • FULL [ OUTER ]
    指定左資料表或右資料表中不符合聯結條件的資料列必須併入結果集中,且對應於其他資料表的輸出資料行必須設為 NULL。這是通常由 INNER JOIN 傳回之所有資料列以外的項目。
  • LEFT [ OUTER ]
    指定左資料表中不符合聯結條件的所有資料列必須併入結果集中,而且,除了內部聯結所傳回的所有資料列以外,還必須將其他資料表中的輸出資料行設為 NULL。
  • RIGHT [OUTER]
    指定右資料表中不符合聯結條件的所有資料列必須併入結果集中,而且,除了內部聯結所傳回的所有資料列以外,還必須將對應於其他資料表的輸出資料行設為 NULL。
  • <join_hint>
    指定 SQL Server 查詢最佳化工具必須使用一個聯結提示,或執行演算法、查詢 FROM 子句中指定的每個聯結。如需詳細資訊,請參閱<聯結提示 (Transact-SQL)>。
  • JOIN
    指出所指定的聯結作業必須發生在所指定的資料表來源或檢視之間。
  • ON <search_condition>
    指定聯結所根據的條件。條件可以指定任何述詞 (雖然通常都是使用資料行和比較運算子),例如:

    SELECT p.ProductID, v.VendorID
    FROM Production.Product AS p 
    JOIN Purchasing.ProductVendor AS v
    ON (p.ProductID = v.ProductID);
    

    當條件指定資料行時,這些資料行不必有相同的名稱或相同的資料類型;不過,如果資料類型不同,它們必須相容的類型或 SQL Server 2005 可以利用隱含方式轉換的類型。如果資料類型無法利用隱含方式轉換,條件必須藉由 CONVERT 函數,利用明確方式轉換資料類型。

    ON 子句中可以有僅涉及其中一個聯結資料表的述詞。這類述詞也可以在查詢的 WHERE 子句中。雖然這類述詞的放置不會影響 INNER 聯結,不過,如果涉及 OUTER 聯結,就可能會造成不同的結果。這是因為 ON 子句中的述詞會套用至聯結之前的資料表,但在語意上,WHERE 子句則套用至聯結的結果。

    如需有關搜尋條件和述詞的詳細資訊,請參閱<搜尋條件 (Transact-SQL)>。

  • CROSS JOIN
    指定兩個資料表的交叉乘積。所傳回的資料列與舊式非 SQL-92 樣式聯結中不指定任何 WHERE 子句時所傳回的資料列相同。
  • left_table_source{ CROSS | OUTER } APPLY right_table_source
    指定必須針對 left_table_source 的每一個資料列來評估 APPLY 運算子的 right_table_source。當 right_table_source 所包含的資料表值函數從 left_table_source 取得資料行值作為它的引數之一時,這項功能就很有用處。

    必須利用 APPLY 指定 CROSS 或 OUTER。當指定 CROSS 時,如果是針對 left_table_source 中的某一個特定資料列來評估 right_table_source,且傳回空的結果集,則不會產生任何資料列。

    當指定 OUTER 時,會為 left_table_source 的每一個資料列產生一個資料列,即使是針對該資料列評估 right_table_source 且傳回空的結果集,亦同。

    如需詳細資訊,請參閱<備註>一節和<使用 APPLY>。

  • left_table_source
    這是資料表來源,如前一個引數所定義的一樣。如需詳細資訊,請參閱<備註>一節。
  • right_table_source
    這是資料表來源,如前一個引數所定義的一樣。如需詳細資訊,請參閱<備註>一節。
  • table_source PIVOT <pivot_clause>
    指定必須根據 pivot_column 來對 table_source 進行樞紐作業。table_source 是資料表或資料表運算式。輸出是一份包含 table_source 之所有資料行 (但不包括 pivot_columnvalue_column) 的資料表。table_source 的資料行 (但不包括 pivot_columnvalue_column) 稱為樞紐運算子的群組作業資料行。

    PIVOT 會對與群組作業資料行相關的輸入資料表執行群組作業,並為每個群組傳回一個資料列。此外,針對 column_list (出現在 input_tablepivot_column 中) 所指定的每個值,輸出還會包含一個資料行。

    如需詳細資訊,請參閱<備註>一節和<使用 PIVOT 和 UNPIVOT>。

    ms177634.note(zh-tw,SQL.90).gif附註:
    當您針對升級為 SQL Server 2005 的資料庫使用 PIVOT 時,資料庫的相容性層級必須設為 90。若要設定資料庫相容性層級,請參閱<sp_dbcmptlevel (Transact-SQL)>。
  • aggregate_function
    這是系統或使用者自訂彙總函數。該彙總函數對 Null 值必須是不變的。對 Null 值不變的彙總函數在評估彙總值時,不會考量群組中的 Null 值。

    不允許使用 COUNT(*) 系統彙總函數。

  • value_column
    這是 PIVOT 運算子的值資料行。當搭配 UNPIVOT 使用時,value_column 不能是輸入 table_source 中現有資料行的名稱。
  • FOR pivot_column
    這是 PIVOT 運算子的樞紐資料行。pivot_column 必須是屬於一種利用隱含或明確方式轉換為 nvarchar() 的類型。這個資料行不可以是 imagerowversion

    當使用 UNPIVOT 時,pivot_column 是指從 table_source 縮短的輸出資料行名稱。含有該名稱的 table_source 中不可以有現有的資料行。

  • IN **(**column_list )
    在 PIVOT 子句中,列出 pivot_column 中會成為輸出資料表之資料行名稱的值。這份清單不能指定已經存在於要進行樞紐作業之輸入 table_source 中的任何資料行名稱。

    在 UNPIVOT 子句中,列出 table_source 中要縮短為單一 pivot_column 的資料行。

  • table_alias
    這是輸出資料表的別名名稱。您必須指定 pivot_table_alias
  • UNPIVOT <unpivot_clause>
    指定要將輸入資料表從 column_list 中的多個資料行縮短為一個稱為 pivot_column 的單一資料行。

    如需詳細資訊,請參閱<備註>一節和<使用 PIVOT 和 UNPIVOT>。

    ms177634.note(zh-tw,SQL.90).gif附註:
    當您針對升級為 SQL Server 2005 的資料庫使用 UNPIVOT 時,資料庫的相容性層級必須設為 90。若要設定資料庫相容性層級,請參閱<sp_dbcmptlevel (Transact-SQL)>。

備註

FROM 子句支援聯結資料表和衍生資料表的 SQL-92-SQL 語法。SQL-92 語法提供 INNER、LEFT OUTER、RIGHT OUTER、FULL OUTER 及 CROSS 聯結運算子。

當資料庫的相容性層級設為 90 時,不支援外部聯結運算子 (*= 和 =*)。

在檢視內的衍生資料表和子查詢中,都支援 FROM 子句內的 UNION 和 JOIN。

自我聯結是指一份聯結至本身的資料表。以自我聯結為基礎的插入或更新作業會遵照 FROM 子句中的順序。

因為 SQL Server 2005 會考量提供資料行散發統計資料之連結伺服器的散發和基數統計資料,所以實際上並不需要利用 REMOTE 聯結提示來從遠端強制評估聯結。SQL Server 查詢處理器會考量遠端統計資料,然後判斷遠端聯結策略是否適當。對於不提供資料行散發統計資料的提供者而言,REMOTE 聯結提示是很有用處的。如需詳細資訊,請參閱<OLE DB Provider 的散發統計資料需求>。

如需有關如何使用聯結的詳細資訊,請參閱<聯結基礎觀念>和<使用聯結>。

使用 APPLY

APPLY 運算子的左運算元和右運算元都是資料表運算式。這兩個運算元的主要差異在於 right_table_source 可以利用資料表值函數,從 left_table_source 取得一個資料行來作為該函數的引數之一。left_table_source 可以包含資料表值函數,但它不能包含由 right_table_source 的資料行構成的引數。

APPLY 運算子利用下列方式來產生 FROM 子句的資料表來源:

  1. 針對 left_table_source 的每個資料列評估 right_table_source,來產生資料列集。
    right_table_source 中的值取決於 left_table_sourceright_table_source 可大約以下列方式代表:TVF(left_table_source.row),其中 TVF 是資料表值的函數。
  2. 執行 UNION ALL 作業,將針對 right_table_source 之評估中的每個資料列產生的結果集與 left_table_source 結合在一起。
    APPLY 運算子的結果所產生的資料行清單,就是與 right_table_source 的資料行清單結合之 left_table_source 的資料行集。

使用 PIVOT 和 UNPIVOT

pivot_columnvalue_column 是 PIVOT 運算子所使用的群組作業資料行。PIVOT 會遵照下列處理序來取得輸出結果集:

  1. 在它的 input_table 上針對群組作業資料行執行 GROUP BY,然後為每個群組分別產生一個輸出。
    輸出資料列中的群組作業資料行會為 input_table 中之該群組取得相對應的資料行值。
  2. 執行下列作業,在每個輸出資料列的資料行清單中產生資料行的值:
    1. 另外,再對前一個步驟中針對 pivot_column 而在 GROUP BY 中所產生的資料列進行群組作業。
      針對 column_list 中的每個輸出資料行,選取滿足下列條件的子群組:
      pivot_column = CONVERT(<data type of pivot_column>, 'output_column')
    2. 針對這個子群組上的 value_column 來評估 aggregate_function,且 aggregate_function 的結果傳回作為相對應的 output_column 之值。如果子群組是空的,SQL Server 會為該 output_column 產生 Null 值。如果彙總函數是 COUNT,且子群組是空的,就會傳回零 (0)。

如需詳細資訊,請參閱<使用 PIVOT 和 UNPIVOT>。

權限

需要 DELETE、SELECT 或 UPDATE 陳述式的權限。

範例

A. 使用簡單的 FROM 子句

下列範例從 AdventureWorks 範例資料庫的 SalesTerritory 資料表中擷取 TerritoryIDName 資料行。

USE AdventureWorks ;
GO
SELECT TerritoryID, Name
FROM Sales.SalesTerritory
ORDER BY TerritoryID ;

以下為結果集:

TerritoryID Name                          
----------- ------------------------------
1           Northwest                     
2           Northeast                     
3           Central                       
4           Southwest                     
5           Southeast                     
6           Canada                        
7           France                        
8           Germany                       
9           Australia                     
10          United Kingdom                
(10 row(s) affected)

B. 使用 TABLOCK 和 HOLDLOCK 最佳化工具提示

下列部分交易顯示如何將明確共用資料表鎖定放在 Employee 上,以及如何讀取索引。整個交易從頭到尾都會保留鎖定。

USE AdventureWorks ;
GO
BEGIN TRAN
SELECT COUNT(*) 
FROM HumanResources.Employee WITH (TABLOCK, HOLDLOCK) ;

C. 使用 SQL-92 CROSS JOIN 語法

下列範例傳回 EmployeeDepartment 這兩個資料表的交叉乘積。傳回一份清單,其中列有 EmployeeID 資料列與所有 Department 名稱資料列兩者的所有可能的組合。

USE AdventureWorks ;
GO
SELECT e.EmployeeID, d.Name AS Department
FROM HumanResources.Employee AS e
CROSS JOIN HumanResources.Department AS d
ORDER BY e.EmployeeID, d.Name ;

D. 使用 SQL-92 FULL OUTER JOIN 語法

下列範例傳回產品名稱和 SalesOrderDetail 資料表中的所有相對應的銷售訂單。它也傳回未在 Product 資料表中列出產品的所有銷售訂單,並傳回含有不同於 Product 資料表所列銷售訂單之銷售訂單的所有產品。

USE AdventureWorks ;
GO
-- The OUTER keyword following the FULL keyword is optional.
SELECT p.Name, sod.SalesOrderID
FROM Production.Product AS p
FULL OUTER JOIN Sales.SalesOrderDetail AS sod
ON p.ProductID = sod.ProductID
WHERE p.ProductID IS NULL OR sod.ProductID IS NULL
ORDER BY p.Name ;

E. 使用 SQL-92 LEFT OUTER JOIN 語法

下列範例聯結 ProductID 上的兩份資料表,並保留左資料表中不相符的資料列。在每一份資料表中,Product 資料表與 ProductID 資料行上的 SalesOrderDetail 資料表相符。所有產品 (已訂購或未訂購) 都會出現在結果集中。

USE AdventureWorks ;
GO
SELECT p.Name, sod.SalesOrderID
FROM Production.Product AS p
LEFT OUTER JOIN Sales.SalesOrderDetail AS sod
ON p.ProductID = sod.ProductID
ORDER BY p.Name ;

F. 使用 SQL-92 INNER JOIN 語法

下列範例傳回所有產品名稱和銷售訂單識別碼。

USE AdventureWorks ;
GO
-- By default, SQL Server performs an INNER JOIN if only the JOIN 
-- keyword is specified.
SELECT p.Name, sod.SalesOrderID
FROM Production.Product AS p
INNER JOIN Sales.SalesOrderDetail AS sod
ON p.ProductID = sod.ProductID
ORDER BY p.Name ;

G. 使用 SQL-92 RIGHT OUTER JOIN 語法

下列範例聯結 TerritoryID 上的兩份資料表,並保留與右資料表中不相符的資料列。在每一份資料表中,SalesTerritory 資料表與 TerritoryID 資料行上的 SalesPerson 資料表相符。所有的銷售員都會出現在結果集中 (不論是否已指派地區給這些銷售員)。

USE AdventureWorks ;
GO
SELECT st.Name AS Territory, sp.SalesPersonID
FROM Sales.SalesTerritory AS st 
RIGHT OUTER JOIN Sales.SalesPerson AS sp
ON st.TerritoryID = sp.TerritoryID ;

H. 使用 HASH 和 MERGE 聯結提示

下列範例從 ProductProductVendorVendor 資料表中執行三資料表聯結,來產生產品及其供應商的清單。查詢最佳化工具利用 MERGE 聯結來聯結 ProductProductVendor ( ppv )。接著,再利用 HASH 聯結將 ProductProductVendor MERGE 聯結 (ppv) 的結果聯結至所要產生的 Vendor 資料表 (ppv) 及 v

ms177634.note(zh-tw,SQL.90).gif重要事項:
指定聯結提示之後,INNER 關鍵字就不再是選擇性質,而是必須針對要執行的 INNER JOIN 加以明確陳述。
USE AdventureWorks ;
GO
SELECT p.Name AS ProductName, v.Name AS VendorName
FROM Production.Product AS p 
INNER MERGE JOIN Purchasing.ProductVendor AS pv 
ON p.ProductID = pv.ProductID
INNER HASH JOIN Purchasing.Vendor AS v
ON pv.VendorID = v.VendorID
ORDER BY p.Name, v.Name ;

I. 使用衍生資料表

下列範例會利用衍生資料表 ( FROM 子句後面的 SELECT 陳述式) 來傳回所有員工的名字和姓氏,以及員工所居住的城市。

USE AdventureWorks ;
GO
SELECT RTRIM(c.FirstName) + ' ' + LTRIM(c.LastName) AS Name,
 d.City
FROM Person.Contact AS c
INNER JOIN HumanResources.Employee e ON c.ContactID = e.ContactID 
INNER JOIN
   (SELECT ea.AddressID, ea.EmployeeID, a.City 
    FROM Person.Address AS a
    INNER JOIN HumanResources.EmployeeAddress AS ea
    ON a.AddressID = ea.AddressID) AS d
ON e.EmployeeID = d.EmployeeID
ORDER BY c.LastName, c.FirstName;

J. 利用 TABLESAMPLE,從資料表的資料列範例中讀取資料

下列範例會利用 FROM 子句中的 TABLESAMPLE,來傳回 AdventureWorks 資料庫 Customer 資料表中所有資料列大約 10% 的資料列。

USE AdventureWorks ;
GO
SELECT *
FROM Sales.Customer TABLESAMPLE SYSTEM (10 PERCENT) ;

K. 使用 APPLY

下列範例假設資料庫中存在含有下列結構描述的下列資料表:

  • Departments: DeptID, DivisionID, DeptName, DeptMgrID
  • EmpMgr: MgrID, EmpID
  • Employees: EmpID, EmpLastName, EmpFirstName, EmpSalary

另外還有一個資料表值的函數 GetReports(MgrID),它會傳回所有員工的清單 ( EmpIDEmpLastNameEmpSalary - 這些項目會直接或間接向指定的 MgrID 報告)。

這個範例利用 APPLY 來傳回所有部門和各部門中的所有員工。如果某特定部門沒有員工,就不會針對該部門傳回任何資料列。

SELECT DeptID, DeptName, DeptMgrID, EmpID, EmpLastName, EmpSalary
FROM Departments d CROSS APPLY dbo.GetReports(d.DeptMgrID) ;

如果您想讓查詢產生沒有員工的部門資料列 (這些資料列會針對 EmpIDEmpLastNameEmpSalary 資料行產生 Null 值),請改用 OUTER APPLY

SELECT DeptID, DeptName, DeptMgrID, EmpID, EmpLastName, EmpSalary
FROM Departments d OUTER APPLY dbo.GetReports(d.DeptMgrID) ;

L. 使用 PIVOT 和 UNPIVOT

下列範例傳回員工識別碼 164198223231233 所放置的訂購單數目 (依照供應商識別碼分類)。

USE AdventureWorks
GO
SELECT VendorID, [164] AS Emp1, [198] AS Emp2, [223] AS Emp3, [231] AS Emp4, [233] AS Emp5
FROM 
(SELECT PurchaseOrderID, EmployeeID, VendorID
FROM Purchasing.PurchaseOrderHeader) AS p
PIVOT
(
COUNT (PurchaseOrderID)
FOR EmployeeID IN
( [164], [198], [223], [231], [233] )
) AS pvt
ORDER BY VendorID;

以下是部分結果集:

VendorID    Emp1        Emp2        Emp3        Emp4        Emp5
1           4           3           5           4           4
2           4           1           5           5           5
3           4           3           5           4           4
4           4           2           5           5           4
5           5           1           5           5           5

若要對資料表執行解除樞紐作業,必須假設前一個範例所產生的結果集是儲存為 pvt。查詢類似如下所示。

--Create the table and insert values as portrayed in the previous example.
CREATE TABLE pvt (VendorID int, Emp1 int, Emp2 int,
Emp3 int, Emp4 int, Emp5 int);
GO
INSERT INTO pvt VALUES (1,4,3,5,4,4);
INSERT INTO pvt VALUES (2,4,1,5,5,5);
INSERT INTO pvt VALUES (3,4,3,5,4,4);
INSERT INTO pvt VALUES (4,4,2,5,5,4);
INSERT INTO pvt VALUES (5,5,1,5,5,5);
GO
--Unpivot the table.
SELECT VendorID, Employee, Orders
FROM 
    (SELECT VendorID, Emp1, Emp2, Emp3, Emp4, Emp5
    FROM pvt) AS p
UNPIVOT
    (Orders FOR Employee IN 
        (Emp1, Emp2, Emp3, Emp4, Emp5)
)AS unpvt
GO

以下是部分結果集:

VendorID    Employee    Orders
1           Emp1        4
1           Emp2        3
1           Emp3        5
1           Emp4        4
1           Emp5        4
2           Emp1        4
2           Emp2        1
2           Emp3        5
2           Emp4        5
2           Emp5        5

請參閱

參考

CONTAINSTABLE (Transact-SQL)
DELETE (Transact-SQL)
FREETEXTTABLE (Transact-SQL)
INSERT (Transact-SQL)
OPENQUERY (Transact-SQL)
OPENROWSET (Transact-SQL)
運算子 (Transact-SQL)
UPDATE (Transact-SQL)
WHERE (Transact-SQL)

說明及資訊

取得 SQL Server 2005 協助

變更歷程記錄

版本 歷程記錄

2005 年 12 月 5 日

變更的內容:
  • 修正範例 I:使用衍生資料表。