안녕하세요...

오늘은 CTE를 사용해서 복잡한 JOIN 구문을 좀 알기 쉽고 편리하게 처리해 볼까 합니다.

먼저 원문입니다.

SELECT

AA.SalesOrderID, AA.SalesLastYear, AA.Bonus, AA.Comment,

BB.AddressID, BB.CustomerID, BB.AccountNumber,

CC.SalesOrderID, CC.SalesPersonID, CC.ShipDate

FROM

(

SELECT

A.SalesOrderID, A.OrderDate, A.Comment, A.SalesPersonID, A.ShipDate, A.CustomerID,

B.Bonus, B.CommissionPct, B.SalesLastYear, B.SalesQuota

FROM Sales.SalesOrderHeader A, Sales.SalesPerson B

WHERE A.SalesPersonID = B.SalesPersonID

AND A.SalesOrderID >= 70000

) AA

LEFT OUTER JOIN

(SELECT

A.CustomerID, A.AccountNumber, A.CustomerType,

B.AddressID, B.AddressTypeID

FROM Sales.Customer A, Sales.CustomerAddress B

WHERE A.CustomerID = B.CustomerID

AND A.CustomerID >= 1 AND A.CustomerID <= 20

) BB

ON AA.CustomerID = BB.CustomerID

LEFT OUTER JOIN

(

SELECT

A.SalesOrderID, A.OrderDate, A.Comment, A.SalesPersonID, A.ShipDate, A.CustomerID,

B.SalesOrderDetailID, B.ProductID, B.OrderQty

FROM Sales.SalesOrderHeader A, Sales.SalesOrderDetail B

WHERE A.SalesOrderID = B.SalesOrderID

AND A.SalesOrderID >= 70000

) CC

ON AA.CustomerID = CC.CustomerID

;

보시는 바와 같이 굵은 줄 친 부분 글씨를 유심히 보지 않으면 JOIN 구문 찾기가 쉽지 않습니다. 이것이 CTE를 사용하지 않은 Sub Query 원문이고요.

만약 이것이 여러 개라면 더더욱 복잡해 지겠지요?

그러면 CTE를 사용해서 정리해 보겠습니다.

WITH AA

AS

(

SELECT

A.SalesOrderID, A.OrderDate, A.Comment, A.SalesPersonID, A.ShipDate, A.CustomerID,

B.Bonus, B.CommissionPct, B.SalesLastYear, B.SalesQuota

FROM Sales.SalesOrderHeader A, Sales.SalesPerson B

WHERE A.SalesPersonID = B.SalesPersonID

AND A.SalesOrderID >= 70000

),

BB AS

(SELECT

A.CustomerID, A.AccountNumber, A.CustomerType,

B.AddressID, B.AddressTypeID

FROM Sales.Customer A, Sales.CustomerAddress B

WHERE A.CustomerID = B.CustomerID

AND A.CustomerID >= 1 AND A.CustomerID <= 20

),

CC AS

(

SELECT

A.SalesOrderID, A.OrderDate, A.Comment, A.SalesPersonID, A.ShipDate, A.CustomerID,

B.SalesOrderDetailID, B.ProductID, B.OrderQty

FROM Sales.SalesOrderHeader A, Sales.SalesOrderDetail B

WHERE A.SalesOrderID = B.SalesOrderID

AND A.SalesOrderID >= 70000

)

SELECT

AA.SalesOrderID, AA.SalesLastYear, AA.Bonus, AA.Comment,

BB.AddressID, BB.CustomerID, BB.AccountNumber,

CC.SalesOrderID, CC.SalesPersonID, CC.ShipDate

FROM

AA LEFT OUTER JOIN BB ON AA.CustomerID = BB.CustomerID

LEFT OUTER JOIN CC ON AA.CustomerID = CC.CustomerID

;

각각 With로 시작하고,

Alias와 , 를 사용한 것 외에는 별 다를 것이 없지만.

FROM 절 아래로 JOIN 구문을 내림으로써 훨씬 보게 좋게 JOIN 확인이 가능합니다. ^^.

간단한 팁이지만, 부득이하게 Sub Query가 많아질 경우 JOIN 관계를 알아보기 힘들게 되므로,

이럴 때 쓰시면 편리하실 듯 하네요. ^^

이상입니다.


* Oracle START WITH ~ CONNECT BY MSSQL 처리하기.

 

# Oracle

SELECT   LEVEL, CATE_ID, LTRIM (SYS_CONNECT_BY_PATH (CATE_NAME, ' > '), ' > ') || ' > ' AS CATE_NAME

      FROM TBL_CATEGORY

START WITH CATE_ID = 1

CONNECT BY PRIOR CATE_ID = PARENT_CATE_ID

 

 

 

# SQL Server

WITH CTE_TABLE

AS

(

       SELECT 1 AS LEVEL, A.CATE_ID, PARENT_CATE_ID, CATE_NAME, CONVERT(VARCHAR(100), CAST(A.CATE_NAME as VARCHAR(100)) + ' > ') AS CATE_NAME

       FROM dbo.TBL_CATEGORY A

       WHERE A.CATE_ID = 1

 

       UNION ALL

      

       SELECT LEVEL + 1, M.CATE_ID, M.PARENT_CATE_ID, M.CATE_NAME, CONVERT(VARCHAR(100), N.CATE_NAME + ' > ' + CAST(M.CATE_NAME AS VARCHAR(100)) + ' > ' ) AS CATE_NAME

       FROM dbo.TBL_CATEGORY M JOIN CTE_TABLE N ON M.PARENT_CATE_ID = N.CATE_ID

)

SELECT * FROM CTE_TABLE

;

+ Recent posts