피할 수없는 상황 CROSS APPLY
이나 OUTER APPLY
.
두 개의 테이블이 있다고 가정하십시오.
마스터 테이블
x------x--------------------x
| Id | Name |
x------x--------------------x
| 1 | A |
| 2 | B |
| 3 | C |
x------x--------------------x
세부 사항 표
x------x--------------------x-------x
| Id | PERIOD | QTY |
x------x--------------------x-------x
| 1 | 2014-01-13 | 10 |
| 1 | 2014-01-11 | 15 |
| 1 | 2014-01-12 | 20 |
| 2 | 2014-01-06 | 30 |
| 2 | 2014-01-08 | 40 |
x------x--------------------x-------x
교차 적용
우리는 교체 할 필요가 많은 상황이있다 INNER JOIN
와 함께 CROSS APPLY
.
1. 기능이있는 TOP n
결과 에 대해 2 개의 테이블을 조인하려는 경우INNER JOIN
우리가 선택해야 할 경우 고려 Id
및 Name
에서 Master
각 마지막 두 날짜 Id
에서 Details table
.
SELECT M.ID,M.NAME,D.PERIOD,D.QTY
FROM MASTER M
INNER JOIN
(
SELECT TOP 2 ID, PERIOD,QTY
FROM DETAILS D
ORDER BY CAST(PERIOD AS DATE)DESC
)D
ON M.ID=D.ID
위 쿼리는 다음 결과를 생성합니다.
x------x---------x--------------x-------x
| Id | Name | PERIOD | QTY |
x------x---------x--------------x-------x
| 1 | A | 2014-01-13 | 10 |
| 1 | A | 2014-01-12 | 20 |
x------x---------x--------------x-------x
마지막 두 날짜의 마지막 두 날짜에 대한 결과를 생성 Id
한 다음 의 외부 쿼리에서만 이러한 레코드를 결합했습니다 Id
. 이는 잘못된 것입니다. 이를 수행하려면 CROSS APPLY
.
SELECT M.ID,M.NAME,D.PERIOD,D.QTY
FROM MASTER M
CROSS APPLY
(
SELECT TOP 2 ID, PERIOD,QTY
FROM DETAILS D
WHERE M.ID=D.ID
ORDER BY CAST(PERIOD AS DATE)DESC
)D
그는 결과를 따라 형성합니다.
x------x---------x--------------x-------x
| Id | Name | PERIOD | QTY |
x------x---------x--------------x-------x
| 1 | A | 2014-01-13 | 10 |
| 1 | A | 2014-01-12 | 20 |
| 2 | B | 2014-01-08 | 40 |
| 2 | B | 2014-01-06 | 30 |
x------x---------x--------------x-------x
여기에 작업이 있습니다. 내부 쿼리 CROSS APPLY
는 외부 테이블을 참조 INNER JOIN
할 수 있지만이를 수행 할 수 없습니다 (컴파일 오류 발생). 마지막 두 날짜를 찾을 때, 내부에서 수행되는 접합 CROSS APPLY
, 즉 WHERE M.ID=D.ID
.
2. INNER JOIN
함수를 사용하여 기능이 필요할 때 .
CROSS APPLY
와 교체로 사용할 수 있습니다 INNER JOIN
우리가에서 결과를 얻을 필요가있을 때 Master
테이블과 function
.
SELECT M.ID,M.NAME,C.PERIOD,C.QTY
FROM MASTER M
CROSS APPLY dbo.FnGetQty(M.ID) C
그리고 여기에 기능이 있습니다
CREATE FUNCTION FnGetQty
(
@Id INT
)
RETURNS TABLE
AS
RETURN
(
SELECT ID,PERIOD,QTY
FROM DETAILS
WHERE ID=@Id
)
다음 결과를 생성했습니다.
x------x---------x--------------x-------x
| Id | Name | PERIOD | QTY |
x------x---------x--------------x-------x
| 1 | A | 2014-01-13 | 10 |
| 1 | A | 2014-01-11 | 15 |
| 1 | A | 2014-01-12 | 20 |
| 2 | B | 2014-01-06 | 30 |
| 2 | B | 2014-01-08 | 40 |
x------x---------x--------------x-------x
외부 적용
1. 기능이있는 TOP n
결과 에 대해 2 개의 테이블을 조인하려는 경우LEFT JOIN
테이블의 Master
각 Id에 대해 Id 및 Name from 과 마지막 두 날짜 를 선택해야하는지 고려하십시오 Details
.
SELECT M.ID,M.NAME,D.PERIOD,D.QTY
FROM MASTER M
LEFT JOIN
(
SELECT TOP 2 ID, PERIOD,QTY
FROM DETAILS D
ORDER BY CAST(PERIOD AS DATE)DESC
)D
ON M.ID=D.ID
다음 결과를 형성하는
x------x---------x--------------x-------x
| Id | Name | PERIOD | QTY |
x------x---------x--------------x-------x
| 1 | A | 2014-01-13 | 10 |
| 1 | A | 2014-01-12 | 20 |
| 2 | B | NULL | NULL |
| 3 | C | NULL | NULL |
x------x---------x--------------x-------x
이것은 잘못된 결과를 가져올 것입니다. 즉, 우리가와 조인하더라도 Details
테이블 에서 최근 두 날짜 데이터 만 가져옵니다 . 따라서 적절한 솔루션은 .Id
Id
OUTER APPLY
SELECT M.ID,M.NAME,D.PERIOD,D.QTY
FROM MASTER M
OUTER APPLY
(
SELECT TOP 2 ID, PERIOD,QTY
FROM DETAILS D
WHERE M.ID=D.ID
ORDER BY CAST(PERIOD AS DATE)DESC
)D
다음과 같은 원하는 결과를 형성합니다.
x------x---------x--------------x-------x
| Id | Name | PERIOD | QTY |
x------x---------x--------------x-------x
| 1 | A | 2014-01-13 | 10 |
| 1 | A | 2014-01-12 | 20 |
| 2 | B | 2014-01-08 | 40 |
| 2 | B | 2014-01-06 | 30 |
| 3 | C | NULL | NULL |
x------x---------x--------------x-------x
2. 우리가 필요로 할 때 LEFT JOIN
사용하는 기능을 functions
.
OUTER APPLY
와 교체로 사용할 수 있습니다 LEFT JOIN
우리가에서 결과를 얻을 필요가있을 때 Master
테이블과 function
.
SELECT M.ID,M.NAME,C.PERIOD,C.QTY
FROM MASTER M
OUTER APPLY dbo.FnGetQty(M.ID) C
그리고 기능은 여기에 있습니다.
CREATE FUNCTION FnGetQty
(
@Id INT
)
RETURNS TABLE
AS
RETURN
(
SELECT ID,PERIOD,QTY
FROM DETAILS
WHERE ID=@Id
)
다음 결과를 생성했습니다.
x------x---------x--------------x-------x
| Id | Name | PERIOD | QTY |
x------x---------x--------------x-------x
| 1 | A | 2014-01-13 | 10 |
| 1 | A | 2014-01-11 | 15 |
| 1 | A | 2014-01-12 | 20 |
| 2 | B | 2014-01-06 | 30 |
| 2 | B | 2014-01-08 | 40 |
| 3 | C | NULL | NULL |
x------x---------x--------------x-------x
CROSS APPLY
및의 공통 기능OUTER APPLY
CROSS APPLY
또는 피벗을 해제 할 때 값 OUTER APPLY
을 유지하는 데 사용할 수 있습니다 NULL
.
아래 표가 있다고 생각하십시오.
x------x-------------x--------------x
| Id | FROMDATE | TODATE |
x------x-------------x--------------x
| 1 | 2014-01-11 | 2014-01-13 |
| 1 | 2014-02-23 | 2014-02-27 |
| 2 | 2014-05-06 | 2014-05-30 |
| 3 | NULL | NULL |
x------x-------------x--------------x
AND 를 하나의 열로 UNPIVOT
가져 오는 데 사용하면 기본적으로 값 이 제거 됩니다.FROMDATE
TODATE
NULL
SELECT ID,DATES
FROM MYTABLE
UNPIVOT (DATES FOR COLS IN (FROMDATE,TODATE)) P
아래 결과를 생성합니다. 우리는 Id
숫자 의 기록을 놓쳤습니다.3
x------x-------------x
| Id | DATES |
x------x-------------x
| 1 | 2014-01-11 |
| 1 | 2014-01-13 |
| 1 | 2014-02-23 |
| 1 | 2014-02-27 |
| 2 | 2014-05-06 |
| 2 | 2014-05-30 |
x------x-------------x
이러한 경우 CROSS APPLY
또는 OUTER APPLY
유용합니다.
SELECT DISTINCT ID,DATES
FROM MYTABLE
OUTER APPLY(VALUES (FROMDATE),(TODATE))
COLUMNNAMES(DATES)
다음 결과를 형성하고 Id
그 가치를 유지합니다 .3
x------x-------------x
| Id | DATES |
x------x-------------x
| 1 | 2014-01-11 |
| 1 | 2014-01-13 |
| 1 | 2014-02-23 |
| 1 | 2014-02-27 |
| 2 | 2014-05-06 |
| 2 | 2014-05-30 |
| 3 | NULL |
x------x-------------x