T-SQL with 키워드 with as 귀속 루프 테이블

19495 단어
Select 글꼴은 논리적으로 SQL 글꼴의 마지막 단계이므로 다음 질의에서 오류가 발생합니다.
SELECT
 YEAR(OrderDate) AS OrderYear,
 COUNT(DISTINCT CustomerID) AS NumCusts
FROM dbo.Orders
GROUP BY OrderYear;

그룹 by는 Select 이전에 진행되었기 때문에 그때orderYear라는 열이 형성되지 않았습니다.
질의에 성공하려면 다음과 같이 수정할 수 있습니다.
SELECT OrderYear, COUNT(DISTINCT CustomerID) AS NumCusts
FROM (SELECT YEAR(OrderDate) AS OrderYear, CustomerID
   FROM dbo.Orders) AS D
GROUP BY OrderYear;

또 하나의 특수한 묘사법이 있다.
SELECT OrderYear, COUNT(DISTINCT CustomerID) AS NumCusts
FROM (SELECT YEAR(OrderDate), CustomerID
   FROM dbo.Orders) AS D(OrderYear, CustomerID)
GROUP BY OrderYear;

작가의 눈에는 더욱 뚜렷하고 명확하며 유지하기 편하기 때문에 그는 이런 작법을 매우 좋아한다.
조회에서 매개 변수의 방향을 사용하여 결과를 생성하는데, 이 기교는 말할 것이 없다.
플러그인 조회는 처리 논리적으로 안에서 밖으로 실행된다.
다중 인용, 아마도 당신의 SQL 문장은 한 테이블에서 여러 번 조회한 후에 연결 조합을 포함하고 있을 것입니다.예를 들어 매년 고객 수와 전년도 고객 수의 변화를 비교해야 하기 때문에 당신의 조회는 반드시 같은 표 두 개의 실례를 가입해야 한다. 이것도 피할 수 없는 것이다.
Common Table Expressions (CTE)
CTE는 SQL2005에 새로 추가된 테이블의 표현 유형입니다.
정의는 다음과 같습니다.
WITH cte_name
AS
(
cte_query
)
outer_query_refferring to_cte_name;
참고: 표준 T-SQL 언어에 이미 WITH 키워드가 포함되어 있기 때문에 구분하기 위해 CTE는 문장의 끝에 ";"를 추가합니다.정지부호로 삼다.
CTE 인스턴스 1(결과 세트 별칭)
WITH C AS
(
 SELECT YEAR(OrderDate) AS OrderYear, CustomerID
 FROM dbo.Orders
)
SELECT OrderYear, COUNT(DISTINCT CustomerID) AS NumCusts
FROM C
GROUP BY OrderYear;

물론 작가 본인은 더욱 추천하는 작법이 있다.
WITH C(OrderYear, CustomerID) AS
(
 SELECT YEAR(OrderDate), CustomerID
 FROM dbo.Orders
)
SELECT OrderYear, COUNT(DISTINCT CustomerID) AS NumCusts
FROM C
GROUP BY OrderYear;

CTE 인스턴스 2(다중 CTEs)
WITH C1 AS
(
 SELECT YEAR(OrderDate) AS OrderYear, CustomerID
 FROM dbo.Orders
),
C2 AS
(
 SELECT OrderYear, COUNT(DISTINCT CustomerID) AS NumCusts
 FROM C1
 GROUP BY OrderYear
)
SELECT OrderYear, NumCusts
FROM C2
WHERE NumCusts > 70;

CTE 인스턴스 3(다중 참조)
WITH YearlyCount AS
(
 SELECT YEAR(OrderDate) AS OrderYear,
  COUNT(DISTINCT CustomerID) AS NumCusts
 FROM dbo.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;

CTE 인스턴스 4(데이터 수정)
1. customer 테이블에서 조회한 결과를 새 테이블에 동적으로 조립합니다. Customers Dups:
IF OBJECT_ID('dbo.CustomersDups') IS NOT NULL
 DROP TABLE dbo.CustomersDups;
GO

WITH CrossCustomers AS
(
 SELECT 1 AS c, C1.*
 FROM dbo.Customers AS C1, dbo.Customers AS C2
)
SELECT ROW_NUMBER() OVER(ORDER BY c) AS KeyCol,
 CustomerID, CompanyName, ContactName, ContactTitle, Address,
 City, Region, PostalCode, Country, Phone, Fax
INTO dbo.CustomersDups
FROM CrossCustomers;

2. CTE를 사용하여 데이터를 제거하고 CustomerDups 테이블의 동일한 CustomerID에서 KeyCol이 가장 큰 기록으로만 유지합니다.
WITH JustDups AS
(
 SELECT * FROM dbo.CustomersDups AS C1
 WHERE KeyCol <
  (SELECT MAX(KeyCol) FROM dbo.CustomersDups AS C2
   WHERE C2.CustomerID = C1.CustomerID)
)
DELETE FROM JustDups;

CTE 인스턴스 5(객체 컨테이너)
즉, 봉인 능력을 제공하여 구성 요소화된 프로그래밍에 유리하다.저자의 추가 알림에 따르면 CTE는 직접 내장할 수 없지만 CTE를 대상 용기에 봉인하고 외부 CTE에서 이 용기의 데이터를 조회하여 내장할 수 있다.
저자도 CTEs를 사용하는 것은 VIEW와 UDFs에서 아무런 가치가 없다고 설명했다.
다음과 같은 예가 있습니다.
CREATE VIEW dbo.VYearCnt
AS
WITH YearCnt AS
(
 SELECT YEAR(OrderDate) AS OrderYear,
  COUNT(DISTINCT CustomerID) AS NumCusts
 FROM dbo.Orders
 GROUP BY YEAR(OrderDate)
)
SELECT * FROM YearCnt;

CTE 인스턴스 6(CTES 반복)
저자는 SQL2005의 새로운 내용인 CTEs의 귀속을 설명하기 위해 예를 하나 주었다.
employeeId에 따라 이 직원의 정보를 되돌려주고 모든 하위 직원의 정보를 포함합니다.(등급 관계는empolyeeId와reportsTo의 속성을 기반으로 함) 다음 필드를 포함합니다.employeeId,reportsTo,FirstName,LastName.
저자는 여기서 가장 좋은 색인 방식을 주었다.
CREATE UNIQUE INDEX idx_mgr_emp_ifname_ilname
 ON dbo.Employees(ReportsTo, EmployeeID)
 INCLUDE(FirstName, LastName);

저자의 설명: 이 인덱스는 하나의 단독 조회 (국부 스캔) 를 통해 모든 사장의 직접적인 하급을 얻을 것이다.포함(FristName, LastName)이 여기에 추가됩니다. 즉, 덮어쓰기 열입니다.
지식: Include 색인은 무엇입니까?
Include 인덱스는 SQL2005의 새로운 기능입니다.Include 인덱스의 열은 인덱스 줄의 물리적 저장 순서에 영향을 주지 않습니다. 그들은 인덱스 줄에 걸립니다.이'걸기'의 목적은 색인 하나만 스캔하면 이 추가 데이터를 얻을 수 있다는 데 있다.
저자의 예로 돌아가면 다음은 귀속 코드입니다.
WITH EmpsCTE AS
(
 SELECT EmployeeID, ReportsTo, FirstName, LastName
 FROM dbo.Employees
 WHERE EmployeeID = 5
 UNION ALL

 SELECT EMP.EmployeeID, EMP.ReportsTo, EMP.FirstName, EMP.LastName
 FROM EmpsCTE AS MGR
  JOIN dbo.Employees AS EMP
   ON EMP.ReportsTo = MGR.EmployeeID
)
SELECT * FROM EmpsCTE;

이해: 귀속된 CTE는 최소 2개의 조회를 포함하고 있으며, 첫 번째 조회는 CTE의 몸에서 닻점과 유사하다.이 닻점은 단지 유효한 시계를 되돌려 주고 돌아오는 닻으로 한다.위의 예에서 보듯이 닻점은employeeID = 5의 한 줄만 되돌려줍니다.그리고 두 번째 조회는 귀속 구성원으로 한다.다음 구성원에 대한 조회 결과가 비어 있으면 이 귀속은 끝납니다.
만약 귀속이 영구 순환을 일으킬까 봐 걱정된다면, 아래의 표현을 사용할 수 있다.
WITH cte_name AS (cte_body) outer_query OPTION (MAXRECURSION n);
기본 n은 100이며 n=0 시 무제한입니다.
http://www.cnblogs.com/wwan/archive/2011/02/24/1964279.html

좋은 웹페이지 즐겨찾기