샘플 데이터
IF OBJECT_ID(N'tempdb..#Tmp') IS NOT NULL DROP TABLE #Tmp
CREATE TABLE #Tmp(id INT NOT NULL, date_time DATETIME NOT NULL, val1 INT, val2 INT)
INSERT INTO #Tmp
VALUES (1, '2020-01-01 12:00:00.00', 1, 2),
(2, '2020-01-01 13:00:00.00', 1, 2)
문제
n > 1
열을 기반으로 일부 ( ) 계산 을 수행한다고 가정합니다 . 그러나, 나는 전에 손이 열을 변환해야합니다 (예를 들어에서 캐스팅 DATETIME
에 DATE
). 다음과 같이 연결된 CTE를 쉽게 사용할 수 있습니다.
WITH trafo (date_only) AS (
SELECT CAST(date_time as DATE) AS date_only
FROM #Tmp
), calc (next_week, prev_week) AS (
SELECT DATEADD(DAY, 7, date_only) AS next_week
, DATEADD(DAY, - 7, date_only) AS prev_week
FROM trafo
)
SELECT *
FROM calc
이런 식으로 저는 CAST(date_time as DATE)
한 번만 작성 하고 DATEADD
부분 에서 반복 할 CAST
필요가 없습니다. (이 특별한 경우에는 이것이 필요하지 않다는 것을 알고 있습니다 .하지만 그게 요점이 아닙니다. 일종의 변형).
그러나 다른 열도 유지하려면 모든 WITH
절 에 복사해야합니다 . 이는 매우 지루해집니다 (특히 열이 꽤 있고 피하고 싶은SELECT *
경우 ).
WITH trafo (id, date_only, val1, val2) AS (
SELECT id
, CAST(date_time as DATE) AS date_only
, val1
, val2
FROM #Tmp
), calc (id, next_week, prev_week, val1, val2) AS (
SELECT id
, DATEADD(DAY, 7, date_only) AS next_week
, DATEADD(DAY, - 7, date_only) AS prev_week
, val1
, val2
FROM trafo
)
SELECT *
FROM calc
첫 번째 WITH
절 에서 관련 열만 선택 JOIN
하고 원래 테이블로 되돌릴 수 있습니다.
WITH trafo (id, date_only) AS (
SELECT id
, CAST(date_time as DATE) AS date_only
FROM #Tmp
), calc (id, next_week, prev_week, val1, val2) AS (
SELECT trafo.id
, DATEADD(DAY, 7, date_only) AS next_week
, DATEADD(DAY, - 7, date_only) AS prev_week
, val1
, val2
FROM trafo
JOIN #Tmp
ON #Tmp.id = trafo.id
)
SELECT *
FROM calc
그러나 이것은 나에게 (성능 측면에서) 매우 현명한 생각이 아닌 것 같습니다 (선택하는 것이 가입하는 것보다 저렴하다고 가정).
질문
원할 때이 문제에 어떻게 접근해야합니까?
ㅏ. 좋은 성능 *
비. 가능한 한 내 코드에서 반복이 적습니까?
* 나는 이것이 실제 사용 사례에 달려 있다는 것을 알고 있지만 불필요한 작업을 피한다는 의미입니다.
이 특정 시나리오는 사용 체인의 이상적인 경우 인 것 같습니다 CROSS/OUTER APPLY
.
WITH trafo (id, date_only, val1, val2) AS (
SELECT id
, CAST(date_time as DATE) AS date_only
, val1
, val2
FROM #Tmp
), calc (id, next_week, prev_week, val1, val2) AS (
SELECT id
, DATEADD(DAY, 7, date_only) AS next_week
, DATEADD(DAY, - 7, date_only) AS prev_week
, val1
, val2
FROM trafo
)
SELECT *
FROM calc
된다 :
SELECT t.id
, t.val1
, t.val2
, s1.date_only
, s2.next_week
, s2.prev_week
FROM #Tmp t
CROSS APPLY (SELECT CAST(t.date_time as DATE) AS date_only) AS s1
CROSS APPLY (SELECT DATEADD(DAY, 7, s1.date_only) AS next_week,
DATEADD(DAY, - 7, s1.date_only) AS prev_week) AS s2
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다