건식 원칙을 SQL 문에 적용하는 방법
-
19-08-2019 - |
문제
다른 사람들 이이 상황을 어떻게 처리하는지 궁금합니다.
나는 T-SQL로 끊임없이 발전하거나 사례 진술을 컬럼으로 현재 몇 달 동안 제시한다는 것을 알았습니다. 나는 일반적으로 (1) 날짜 필드 및 (2) 값 필드를 포함하는 일부 분야가 있습니다. ASPX 페이지 또는보고 서비스를 통해 사용자에게 다시 제시하면이 패턴을 갖기 위해서는 마지막으로 올바른 14 열이 있어야합니다.
Year], [Jan], [Feb], [Mar], [Apr], [May], [Jun], [Jun], [7 월], [Aug], [Sep], [10 월], [Nov], [DEC ],[총
연도는 int로 연도이고 다른 모든 분야는 해당 달의 가치 필드입니다 (총 가치 필드 인 [총] 제외).
이것을 처리 할 수있는 재사용 가능한 한 가지 방법을 찾고 싶습니다. 모든 제안에 개방 (T-SQL / ANSI SQL)
해결책
이것은 정확히 당신이 찾고있는 것이 아니지만, 나는 많은 반복적 인 일을했습니다. UNPIVOT
, 그리고 일반적으로, 나는 어떤 종류의 표준화 된 이름 지정과 함께 코드-그린 다음 CTE를 많이 사용합니다.
WITH P AS (
SELECT Some Data
,[234] -- These are stats
,[235]
FROM Whatever
)
,FINAL_UNPIVOTED AS (
SELECT Some Data
,[STAT]
FROM P
UNPIVOT (
STAT FOR BASE IN ([234], [235])
) AS unpvt
WHERE STAT <> 0
)
SELECT Some Data
,CONVERT(int, FINAL_UNPIVOTED.[BASE]) AS [BASE]
,FINAL_UNPIVOTED.[STAT]
FROM FINAL_UNPIVOTED
테이블이나 뷰를 검사하고 다음과 같은 것을 사용하여 코딩 할 수 있습니다.
DECLARE @sql_unpivot AS varchar(MAX)
SELECT @sql_unpivot = COALESCE(@sql_unpivot + ',', '') + COLUMN_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = 'whatever'
그리고 코드를 템플릿 화 :
SET @template = '
WITH P AS (
SELECT Some Data
,{@sql_unpivot}
FROM Whatever
)
,FINAL_UNPIVOTED AS (
SELECT Some Data
,[STAT]
FROM P
UNPIVOT (
STAT FOR BASE IN ({@sql_unpivot})
) AS unpvt
WHERE STAT <> 0
)
SELECT Some Data
,CONVERT(int, FINAL_UNPIVOTED.[BASE]) AS [BASE]
,FINAL_UNPIVOTED.[STAT]
FROM FINAL_UNPIVOTED
'
SET @sql = REPLACE(@template, '{@sql_unpivot}', @sql_unpivot)
등.
물론,이 코드를 동적으로 실행하거나 생성 및 SP를 실행할 수 있으며, 일시적으로 만든 뷰 또는 테이블을 인라인으로 선택할 수 있습니다.
테이블 값 기능 및 외부 적용 기술에 관한 의견을 참조하십시오.
다른 팁
늦었고 여기서 명백한 것을 놓치고 있을지 모르지만 매월 행이 달린 달이 달린 도와 드릴까요?
/* I leave year and month separate so you can use "real" Months or Fiscal Months */
CREATE FUNCTION [dbo].[fn_MonthValueColumns]
(
@year int,
@month int,
@measure int
)
RETURNS TABLE
AS
RETURN
(
SELECT @year as [Year],
CASE WHEN @month = 1 THEN @measure ELSE 0 END AS [Jan],
CASE WHEN @month = 2 THEN @measure ELSE 0 END AS [Feb],
CASE WHEN @month = 3 THEN @measure ELSE 0 END AS [Mar],
CASE WHEN @month = 4 THEN @measure ELSE 0 END AS [Apr],
CASE WHEN @month = 5 THEN @measure ELSE 0 END AS [May],
CASE WHEN @month = 6 THEN @measure ELSE 0 END AS [Jun],
CASE WHEN @month = 7 THEN @measure ELSE 0 END AS [Jul],
CASE WHEN @month = 8 THEN @measure ELSE 0 END AS [Aug],
CASE WHEN @month = 9 THEN @measure ELSE 0 END AS [Sep],
CASE WHEN @month = 10 THEN @measure ELSE 0 END AS [Oct],
CASE WHEN @month = 11 THEN @measure ELSE 0 END AS [Nov],
CASE WHEN @month = 12 THEN @measure ELSE 0 END AS [Dec],
@measure AS [Total]
)
/*
use a group by after your own CROSS APPLY to roll-up SUMs for the last 13 fields.
this function and a CROSS APPLY against 100000 records ran in 3 seconds.
for what I am doing, I can live with that performance.
*/
보기를 사용하는 것은 어떻습니까?
항상 같은 테이블/그룹의 테이블을 사용하는 경우보기가 이해가 될 수 있습니다. 경고 : 큰 테이블의 작은 섹션을 사용할 때 그러한 견해를 조심하십시오.보기는 최적화가 작업을 수행하지 못하게 할 수 있습니다.