이 문서는 수동으로 번역한 것입니다. 원본 텍스트를 보려면 포인터를 문서의 문장 위로 올리십시오. |
번역
원본
|
FROM(Transact-SQL)
SQL Server 2012에서 DELETE, SELECT, UPDATE 문에 사용되는 테이블, 뷰, 파생된 테이블 문 조인된 테이블을 지정합니다. SELECT 문에서 SELECT 목록에 상수, 변수 및 산술식(열 이름 없이)만 포함되는 경우를 제외하고는 FROM 절이 필요합니다.
[ 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 ] ]
| 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> [ AS ] table_alias
<pivot_clause> ::=
( aggregate_function ( value_column [ [ , ]...n ])
FOR pivot_column
IN ( <column_list> )
)
<unpivoted_table> ::=
table_source UNPIVOT <unpivot_clause> [ AS ] table_alias
<unpivot_clause> ::=
( value_column FOR pivot_column IN ( <column_list> ) )
<column_list> ::=
column_name [ ,...n ]
FROM 절은 조인된 테이블과 파생된 테이블에 대해 SQL-92-SQL 구문을 지원합니다. SQL-92 구문은 INNER, LEFT OUTER, RIGHT OUTER, FULL OUTER, CROSS 조인 연산자를 제공합니다.
FROM 절의 UNION과 JOIN은 뷰, 파생된 테이블 및 하위 쿼리에서 지원됩니다.
자체 조인은 자신을 조인하는 테이블을 말합니다. 자체 조인을 기반으로 하는 삽입이나 업데이트 작업은 FROM 절에 지정된 순서를 따릅니다.
SQL Server는 열 배포 통계를 제공하는 연결된 서버에서 배포 통계와 카디널리티 통계를 고려하므로, 조인을 원격에서 수행하기 위해 REMOTE 조인 힌트가 필요하지는 않습니다. SQL Server 쿼리 프로세서는 원격 통계를 고려하여 원격 조인 전략이 적절한지 결정합니다. REMOTE 조인 힌트는 열 배포 통계를 제공하지 않는 공급자에게 유용합니다.
APPLY 사용
APPLY 연산자의 좌우 피연산자는 모두 테이블 식입니다. 이 피연산자 간의 주된 차이점은 right_table_source가 left_table_source의 열을 함수의 인수 중 하나로 사용하는 테이블 반환 함수를 사용할 수 있다는 것입니다. left_table_source는 테이블 반환 함수를 포함할 수 있지만 right_table_source의 열인 인수는 포함할 수 없습니다.
APPLY 연산자는 다음과 같은 방식으로 FROM 절에 지정될 테이블 원본을 생성합니다.
-
left_table_source의 각 행에 대해 right_table_source를 계산하여 행 집합을 생성합니다.
right_table_source 값은 left_table_source에 따라 달라집니다. right_table_source는 다음과 같이 표현될 수 있습니다. TVF(left_table_source.row)와 같이 표현될 수 있습니다. 여기서 TVF는 테이블 반환 함수입니다.
-
UNION ALL 연산을 수행하여 right_table_source 계산 시 각 행에 대해 생성된 결과 집합을 left_table_source와 결합합니다.
APPLY 연산자의 결과로 생성된 열 목록은 right_table_source의 열 목록과 결합된 left_table_source의 열 집합입니다.
PIVOT 및 UNPIVOT 사용
pivot_column 및 value_column은 PIVOT 연산자에 사용되는 그룹화 열입니다. PIVOT은 다음과 같은 방식으로 출력 결과 집합을 가져옵니다.
-
input_table에서 그룹화 열을 기준으로 GROUP BY를 수행해 각 그룹당 한 개의 출력 행을 생성합니다.
출력 행의 그룹화 열은 input_table의 해당 그룹에 대한 열 값을 가져옵니다.
-
다음 작업을 수행해 각각의 출력 행에 대한 열 목록의 열 값을 생성합니다.
-
이전 단계에서 GROUP BY를 수행하여 생성된 행을 pivot_column을 기준으로 추가 그룹화합니다.
column_list의 각 출력 열에 대해 조건을 만족하는 하위 그룹을 선택합니다.
pivot_column = CONVERT(<data type of pivot_column>, 'output_column')
-
이 하위 그룹의 value_column에 대해 aggregate_function이 계산되고 그 결과는 해당하는 output_column의 값으로 반환됩니다. 하위 그룹이 비어 있으면 SQL Server는 해당 output_column의 값으로 Null을 생성합니다. 집계 함수가 COUNT이고 하위 그룹이 비어 있으면 0이 반환됩니다.
-
1.간단한 FROM 절 사용
다음 예에서는 AdventureWorks2012 샘플 데이터베이스에서 SalesTerritory 테이블의 TerritoryID 및 Name을 검색합니다.
USE AdventureWorks2012 ; 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)
2.TABLOCK 및 HOLDLOCK 최적화 프로그램 힌트 사용
다음의 부분 트랜잭션은 Employee에 명시적인 공유 테이블 잠금을 설정하고 인덱스를 읽는 방법을 보여 줍니다. 잠금은 전체 트랜잭션 동안 유지됩니다.
USE AdventureWorks2012 ; GO BEGIN TRAN SELECT COUNT(*) FROM HumanResources.Employee WITH (TABLOCK, HOLDLOCK) ;
3.SQL-92 CROSS JOIN 구문 사용
다음 예에서는 Employee 및 Department라는 두 테이블의 교차곱을 반환합니다. BusinessEntityID 행과 모든 Department 이름 행의 가능한 모든 조합 목록이 반환됩니다.
USE AdventureWorks2012 ; GO SELECT e.BusinessEntityID, d.Name AS Department FROM HumanResources.Employee AS e CROSS JOIN HumanResources.Department AS d ORDER BY e.BusinessEntityID, d.Name ;
4.SQL-92 FULL OUTER JOIN 구문 사용
다음 예에서는 SalesOrderDetail 테이블의 제품 이름 및 해당되는 모든 판매 주문을 반환합니다. 또한 Product 테이블에 나열되어 있는 제품이 없는 모든 판매 주문, 그리고 Product 테이블에 나열된 것 이외의 주문된 모든 제품을 반환합니다.
USE AdventureWorks2012 ; 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 ;
5.SQL-92 LEFT OUTER JOIN 구문 사용
다음 예에서는 ProductID로 두 테이블을 조인하고 왼쪽 테이블에서 일치하지 않는 행도 함께 반환합니다. Product 테이블은 ProductID 열에서 각 SalesOrderDetail 테이블과 일치합니다. 모든 제품은 주문 여부에 관계없이 결과 집합에 나타납니다.
USE AdventureWorks2012 ; 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 ;
6.SQL-92 INNER JOIN 구문 사용
다음 예에서는 모든 제품 이름과 판매 주문 ID를 반환합니다.
USE AdventureWorks2012 ; 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 ;
7.SQL-92 RIGHT OUTER JOIN 구문 사용
다음 예에서는 TerritoryID로 두 테이블을 조인하고 오른쪽 테이블에서 일치하지 않는 행도 함께 반환합니다. SalesTerritory 테이블은 TerritoryID 열에서 각 SalesPerson 테이블과 일치합니다. 판매 직원에게 담당 구역이 할당되었는지 여부에 관계없이 모든 판매 직원이 결과 집합에 표시됩니다.
USE AdventureWorks2012 ; GO SELECT st.Name AS Territory, sp.BusinessEntityID FROM Sales.SalesTerritory AS st RIGHT OUTER JOIN Sales.SalesPerson AS sp ON st.TerritoryID = sp.TerritoryID ;
8.HASH 및 MERGE 조인 힌트 사용
다음 예에서는 Product, ProductVendor 및 Vendor 테이블 간의 3개 테이블 조인을 수행하여 제품 및 제품 공급업체 목록을 생성합니다. 쿼리 최적화 프로그램은 MERGE 조인을 사용하여 Product와 ProductVendor(p와 pv)를 조인합니다. 그런 다음 Product와 ProductVendor(p와 pv)의 MERGE 조인이 Vendor 테이블에 HASH 조인되어 (p와 pv) 및 v를 생성합니다.
중요
|
|---|
|
조인 힌트를 지정한 이후에는 INNER 키워드가 더 이상 선택 사항이 아니며 INNER JOIN을 수행하도록 명시적으로 지정해야 합니다. |
USE AdventureWorks2012 ; 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.BusinessEntityID = v.BusinessEntityID ORDER BY p.Name, v.Name ;
9.파생된 테이블 사용
다음 예에서는 파생된 테이블과 SELECT 문을 FROM 절 다음에 사용하여 모든 직원의 성과 이름, 직원이 거주하는 도시를 반환합니다.
USE AdventureWorks2012 ;
GO
SELECT RTRIM(p.FirstName) + ' ' + LTRIM(p.LastName) AS Name, d.City
FROM Person.Person AS p
INNER JOIN HumanResources.Employee e ON p.BusinessEntityID = e.BusinessEntityID
INNER JOIN
(SELECT bea.BusinessEntityID, a.City
FROM Person.Address AS a
INNER JOIN Person.BusinessEntityAddress AS bea
ON a.AddressID = bea.AddressID) AS d
ON p.BusinessEntityID = d.BusinessEntityID
ORDER BY p.LastName, p.FirstName;
10.TABLESAMPLE을 사용하여 테이블의 행 샘플 데이터 읽기
다음 예에서는 FROM 절에 TABLESAMPLE을 사용하여 Customer 테이블에 있는 모든 행 중 대략 10 퍼센트를 반환합니다.
USE AdventureWorks2012 ; GO SELECT * FROM Sales.Customer TABLESAMPLE SYSTEM (10 PERCENT) ;
11.APPLY 사용
다음 예에서는 다음 스키마를 가진 테이블이 데이터베이스에 존재하는 것으로 가정합니다.
-
Departments: DeptID, DivisionID, DeptName, DeptMgrID
-
EmpMgr: MgrID, EmpID
-
Employees: EmpID, EmpLastName, EmpFirstName, EmpSalary
또 다른 테이블 반환 함수인 GetReports(MgrID)는 지정된 MgrID에 직접 또는 간접적으로 보고하는 모든 직원의 목록(EmpID, EmpLastName, EmpSalary)을 반환합니다.
이 예에서는 APPLY를 사용하여 모든 부서와 해당 부서의 모든 직원을 반환합니다. 특정 부서에 직원이 한 명도 없으면 해당 부서에 대해서는 행이 반환되지 않습니다.
SELECT DeptID, DeptName, DeptMgrID, EmpID, EmpLastName, EmpSalary FROM Departments d CROSS APPLY dbo.GetReports(d.DeptMgrID) ;
쿼리가 직원이 없는 부서의 행도 생성하도록 하려면 OUTER APPLY를 사용하십시오. 이 때 EmpID, EmpLastName 및 EmpSalary 열에 대해서는 Null 값이 생성됩니다.
SELECT DeptID, DeptName, DeptMgrID, EmpID, EmpLastName, EmpSalary FROM Departments d OUTER APPLY dbo.GetReports(d.DeptMgrID) ;
12.PIVOT 및 UNPIVOT 사용
다음 예에서는 공급업체 ID별로 분류된 직원 ID 164, 198, 223, 231 및 233에 의해 작성된 구매 주문 번호를 반환합니다.
USE AdventureWorks2012; GO SELECT VendorID, [250] AS Emp1, [251] AS Emp2, [256] AS Emp3, [257] AS Emp4, [260] AS Emp5 FROM (SELECT PurchaseOrderID, EmployeeID, VendorID FROM Purchasing.PurchaseOrderHeader) AS p PIVOT ( COUNT (PurchaseOrderID) FOR EmployeeID IN ( [250], [251], [256], [257], [260] ) ) 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 dbo.pvt (VendorID int, Emp1 int, Emp2 int,
Emp3 int, Emp4 int, Emp5 int);
GO
INSERT INTO dbo.pvt VALUES
(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);
GO
--Unpivot the table.
SELECT VendorID, Employee, Orders
FROM
(SELECT VendorID, Emp1, Emp2, Emp3, Emp4, Emp5
FROM dbo.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
13.CROSS APPLY 사용
다음 예제는 sys.dm_exec_cached_plans 동적 관리 뷰를 쿼리하여 캐시에 있는 모든 쿼리 계획의 계획 핸들을 검색함으로써 계획 캐시에 있는 모든 쿼리 계획의 스냅숏을 검색합니다. 그런 다음 sys.dm_exec_query_plan에 계획 핸들을 전달할 CROSS APPLY 연산자를 지정합니다. 계획 캐시에 있는 각 계획의 XML 실행 계획 출력은 현재 반환된 테이블의 query_plan 열에 있습니다.
USE master; GO SELECT dbid, object_id, query_plan FROM sys.dm_exec_cached_plans AS cp CROSS APPLY sys.dm_exec_query_plan(cp.plan_handle); GO
참고
중요