답변:
예를 들어, 동일한 데이터 세트를 여러 번 참조 / 결합해야하는 경우 CTE를 정의하면됩니다. 따라서 코드 재사용 형식이 될 수 있습니다.
자체 참조의 예는 재귀입니다. CTE를 사용한 재귀 쿼리
온라인 설명서에서 가져온 흥미로운 Microsoft 정의 :
CTE를 사용하여 다음을 수행 할 수 있습니다.
재귀 쿼리를 만듭니다. 자세한 내용은 공통 테이블 식을 사용한 재귀 쿼리를 참조하십시오 .
뷰를 일반적으로 사용할 필요가없는 뷰를 대체합니다. 즉, 정의를 메타 데이터에 저장할 필요가 없습니다.
스칼라 부속 선택에서 파생 된 열 또는 결정적이지 않거나 외부 액세스 권한이있는 함수를 기준으로 그룹화를 사용하십시오.
동일한 명령문에서 결과 테이블을 여러 번 참조하십시오.
select top 100 * into #tmp from master..spt_values order by 1,2,3,4 select A.number, COUNT(*) from #tmp A inner join #tmp B ON A.number = B.number+1 group by A.number
vswith CTE AS (select top 100 * from master..spt_values order by 1,2,3,4) select A.number, COUNT(*) from CTE A inner join CTE B ON A.number = B.number+1 group by A.number
복잡한 쿼리, 특히 복잡한 조인 및 하위 쿼리를 분리하는 데 사용합니다. 쿼리의 의도를 이해하는 데 도움이되는 '의사보기'로 점점 더 많이 사용하고 있습니다.
그들에 대한 나의 유일한 불만은 재사용 할 수 없다는 것입니다. 예를 들어, 동일한 CTE를 사용할 수있는 두 개의 업데이트 문이있는 저장 프로 시저가있을 수 있습니다. 그러나 CTE의 '범위'는 첫 번째 쿼리 일뿐입니다.
문제는 '간단한 예'에는 실제로 CTE가 필요하지 않을 것입니다!
여전히 매우 편리합니다.
VIEW
:)
cte를 사용하는 데는 두 가지 이유가 있습니다.
where 절에서 계산 된 값을 사용합니다. 이것은 파생 테이블보다 조금 더 깨끗해 보입니다.
Questions.ID = Answers.Question_Id (및 퀴즈 ID)로 결합 된 질문과 답변이라는 두 개의 테이블이 있다고 가정합니다.
WITH CTE AS
(
Select Question_Text,
(SELECT Count(*) FROM Answers A WHERE A.Question_ID = Q.ID) AS Number_Of_Answers
FROM Questions Q
)
SELECT * FROM CTE
WHERE Number_Of_Answers > 0
다음은 질문과 답변 목록을 얻고 싶은 또 다른 예입니다. 답변을 결과의 질문과 그룹화하고 싶습니다.
WITH cte AS
(
SELECT [Quiz_ID]
,[ID] AS Question_Id
,null AS Answer_Id
,[Question_Text]
,null AS Answer
,1 AS Is_Question
FROM [Questions]
UNION ALL
SELECT Q.[Quiz_ID]
,[Question_ID]
,A.[ID] AS Answer_Id
,Q.Question_Text
,[Answer]
,0 AS Is_Question
FROM [Answers] A INNER JOIN [Questions] Q ON Q.Quiz_ID = A.Quiz_ID AND Q.Id = A.Question_Id
)
SELECT
Quiz_Id,
Question_Id,
Is_Question,
(CASE WHEN Answer IS NULL THEN Question_Text ELSE Answer END) as Name
FROM cte
GROUP BY Quiz_Id, Question_Id, Answer_id, Question_Text, Answer, Is_Question
order by Quiz_Id, Question_Id, Is_Question Desc, Name
HAVING
서브를 사용하는 것과 유사 할 수있는 마지막 단계 필터 할 수있는 또 다른 방법입니다SELECT
CTE를 사용하는 데 유용한 시나리오 중 하나는 하나 이상의 열을 기반으로 DISTINCT 행의 데이터를 가져오고 테이블의 모든 열을 반환하려는 경우입니다. 표준 쿼리를 사용하면 먼저 고유 값을 임시 테이블에 덤프 한 다음 원래 테이블에 다시 결합하여 나머지 열을 검색하거나 결과를 반환 할 수있는 매우 복잡한 파티션 쿼리를 작성할 수 있습니다 한 번 실행하지만 대부분의 경우 읽을 수 없으며 성능 문제가 발생합니다.
그러나 CTE를 사용함으로써 (팀 Schmelter 가 레코드의 첫 번째 인스턴스 를 선택했을 때 )
WITH CTE AS(
SELECT myTable.*
, RN = ROW_NUMBER()OVER(PARTITION BY patientID ORDER BY ID)
FROM myTable
)
SELECT * FROM CTE
WHERE RN = 1
보다시피, 이것은 읽고 유지하기가 훨씬 쉽습니다. 다른 쿼리와 비교할 때 성능이 훨씬 뛰어납니다.
CTE를 단일 쿼리에 사용되는 뷰 대신 사용하는 것이 더 의미가있을 수 있습니다. 그러나 공식적인 관점의 오버 헤드, 메타 데이터 또는 지속성이 필요하지 않습니다. 다음과 같은 경우에 매우 유용합니다.
잘라 내기 및 붙여 넣기 예제는 다음과 같습니다.
WITH [cte_example] AS (
SELECT 1 AS [myNum], 'a num' as [label]
UNION ALL
SELECT [myNum]+1,[label]
FROM [cte_example]
WHERE [myNum] <= 10
)
SELECT * FROM [cte_example]
UNION
SELECT SUM([myNum]), 'sum_all' FROM [cte_example]
UNION
SELECT SUM([myNum]), 'sum_odd' FROM [cte_example] WHERE [myNum] % 2 = 1
UNION
SELECT SUM([myNum]), 'sum_even' FROM [cte_example] WHERE [myNum] % 2 = 0;
즐겨
오늘 우리는 SQL Server 2005에 도입되었고 이후 버전에서도 사용할 수있는 새로운 기능인 공통 테이블 표현식에 대해 배울 것입니다.
공통 테이블 표현식 :-공통 테이블 표현식은 임시 결과 세트 또는 다른 말로 SQL Server에서 뷰를 대체 할 수 있습니다. 공통 테이블 표현식은 명령문이 정의 된 배치 배치에서만 유효하며 다른 세션에서는 사용할 수 없습니다.
CTE (Common Table Expression) 선언 구문 :-
with [Name of CTE]
as
(
Body of common table expression
)
예를 들어 보자.
CREATE TABLE Employee([EID] [int] IDENTITY(10,5) NOT NULL,[Name] [varchar](50) NULL)
insert into Employee(Name) values('Neeraj')
insert into Employee(Name) values('dheeraj')
insert into Employee(Name) values('shayam')
insert into Employee(Name) values('vikas')
insert into Employee(Name) values('raj')
CREATE TABLE DEPT(EID INT,DEPTNAME VARCHAR(100))
insert into dept values(10,'IT')
insert into dept values(15,'Finance')
insert into dept values(20,'Admin')
insert into dept values(25,'HR')
insert into dept values(10,'Payroll')
두 개의 테이블 employee와 Dept를 작성하고 각 테이블에 5 개의 행을 삽입했습니다. 이제이 테이블을 조인하고 더 사용하기 위해 임시 결과 집합을 만들고 싶습니다.
With CTE_Example(EID,Name,DeptName)
as
(
select Employee.EID,Name,DeptName from Employee
inner join DEPT on Employee.EID =DEPT.EID
)
select * from CTE_Example
성명서의 각 줄을 하나씩 살펴보고 이해합시다.
CTE를 정의하기 위해 "with"절을 쓴 다음 테이블 표현식에 이름을 지정합니다. 여기서는 "CTE_Example"이라는 이름을 지정했습니다.
그런 다음 "As"를 작성하고 코드를 두 개의 괄호 (---)로 묶으면 동봉 된 괄호로 여러 테이블을 조인 할 수 있습니다.
마지막 줄에서 "Select * from CTE_Example"을 사용했고, 마지막 코드 줄에서 공통 테이블 표현식을 참조하고 있습니다. 배치 및 CTE는 데이터베이스에 영구 객체로 저장되지 않습니다. 그러나 그것은보기처럼 행동합니다. CTE에서 delete 및 update 문을 수행 할 수 있으며 CTE에서 사용중인 참조 테이블에 직접적인 영향을 미칩니다. 이 사실을 이해하기 위해 예를 들어 봅시다.
With CTE_Example(EID,DeptName)
as
(
select EID,DeptName from DEPT
)
delete from CTE_Example where EID=10 and DeptName ='Payroll'
위의 명령문에서 CTE_Example에서 행을 삭제하고 CTE에서 사용중인 참조 테이블 "DEPT"에서 데이터를 삭제합니다.
"순서 업데이트"를 수행 할 때 매우 유용합니다.
MS SQL에서는 ORDER BY를 UPDATE와 함께 사용할 수 없지만 CTE의 도움으로 다음과 같이 할 수 있습니다.
WITH cte AS
(
SELECT TOP(5000) message_compressed, message, exception_compressed, exception
FROM logs
WHERE Id >= 5519694
ORDER BY Id
)
UPDATE cte
SET message_compressed = COMPRESS(message), exception_compressed = COMPRESS(exception)
자세한 내용은 여기를 참조하십시오. ms sql을 사용하여 업데이트하고 주문하는 방법
아직 지적하지 않은 한 가지는 속도 입니다. 나는 이것이 오래된 답변이라는 것을 알고 있지만 이것은 직접적인 의견 / 답변이 필요하다고 생각합니다.
파생 테이블로 동일하게 수행 할 수 있으므로 중복되는 것처럼 보입니다.
CTE를 처음 사용했을 때는 속도에 크게 놀랐습니다. 그것은 CTE에 매우 적합한 교과서와 같은 경우이지만 CTE를 사용한 모든 사건에서 상당한 속도 향상이있었습니다. 첫 번째 쿼리는 파생 테이블이 복잡하여 실행하는 데 시간이 오래 걸렸습니다. CTE를 사용하면 몇 초가 걸렸으며 충격을 받았습니다.