동적으로 생성 된 열이있는 피벗 테이블을 사용하여 월별 작업을 계산하는 보고서를 만듭니다. 동적 쿼리 내에서 세 개의 열과 관련된 CROSS APPLY가 있습니다. 이것은 내 합계가 3 배 이상 커야합니다. 나는 현재 정확한 해답을 얻으려고 카운트를 3으로 나누는 해킹을하고있다. 누구든지이 문제에 대한보다 우아한 해결책을 찾도록 도와 줄 수 있습니까?SQL 피봇 테이블이 집계 결과에 교차 적용합니다.
편집 :
CREATE TABLE vw_ActionsReport
([CID] int, [MitigationActionID] int, [Approved] int, [Status] varchar(11), [ChangedDate] datetime, [EntryDate] varchar(7), [STATE_ABBR] varchar(2), [STATE_NAME] varchar(11), [CENSUS_NAM] varchar(12), [CIS_NAME] varchar(21), [COUNTY_NAM] varchar(9), [CO_FIPS] int, [REGION] int, [ST_FIPS] int);
INSERT INTO vw_ActionsReport
([CID], [MitigationActionID], [Approved], [Status], [ChangedDate], [EntryDate], [STATE_ABBR], [STATE_NAME], [CENSUS_NAM], [CIS_NAME], [COUNTY_NAM], [CO_FIPS], [REGION], [ST_FIPS])
VALUES
(090069, 5475, 1, 'Identified', '2012-11-27 16:21:27', '11_2012', 'CT', 'CONNECTICUT', 'OLD SAYBROOK', 'OLD SAYBROOK, TOWN OF', 'MIDDLESEX', 09007, 01, 09),
(090069, 5476, 1, 'In Progress', '2012-11-27 16:21:27', '11_2012', 'CT', 'CONNECTICUT', 'OLD SAYBROOK', 'OLD SAYBROOK, TOWN OF', 'MIDDLESEX', 09007, 01, 09),
(090012, 6687, 1, 'Identified', '2013-04-02 16:14:03', '4_2013', 'CT', 'CONNECTICUT', 'NORWALK', 'NORWALK, CITY OF', 'FAIRFIELD', 09001, 01, 09),
(090008, 6993, 1, 'Identified', '2013-06-20 15:18:38', '6_2013', 'CT', 'CONNECTICUT', 'GREENWICH', 'GREENWICH, TOWN OF', 'FAIRFIELD', 09001, 01, 09),
(090019, 17000, 0, 'Identified', '2013-11-26 11:46:14', '11_2013', 'CT', 'CONNECTICUT', 'WESTPORT', 'WESTPORT, TOWN OF', 'FAIRFIELD', 09001, 01, 09);
: 나는 (실제로 도면이다하지만 난 그게 SO의 전체 스키마를 다시하는 것이 현명했다 느끼지 않았다)이 데이터 집합을 감안할 때 SQL 서버 2008R2
을 사용하고 있습니다
그런 다음, 다음과 같은 쿼리를 사용 :
DECLARE @cols AS NVARCHAR(MAX),
@cols_math AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX);
SELECT @cols = STUFF
(
(
SELECT ',' + QUOTENAME(EntryDate)
FROM dbo.vw_ActionsReport
GROUP BY EntryDate,
DATEPART(YEAR, dbo.vw_ActionsReport.ChangedDate),
DATEPART(MONTH, dbo.vw_ActionsReport.ChangedDate)
ORDER BY DATEPART(YEAR, dbo.vw_ActionsReport.ChangedDate),
DATEPART(MONTH, dbo.vw_ActionsReport.ChangedDate)
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'),
1,1,''
);
SELECT @cols_math = STUFF
(
(
-- This is my hack where I divide the answer by three
SELECT ',' + QUOTENAME(EntryDate) + '/3 AS ' + QUOTENAME(EntryDate)
FROM dbo.vw_ActionsReport
GROUP BY EntryDate,
DATEPART(YEAR, dbo.vw_ActionsReport.ChangedDate),
DATEPART(MONTH, dbo.vw_ActionsReport.ChangedDate)
ORDER BY DATEPART(YEAR, dbo.vw_ActionsReport.ChangedDate),
DATEPART(MONTH, dbo.vw_ActionsReport.ChangedDate)
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'),
1,1,''
);
SET @query = 'SELECT REGION, STATE_ABBR, [Status],' + @cols_math + ' FROM
(
SELECT REGION, STATE_ABBR, [Status], EntryDate, MitigationActionID
FROM dbo.vw_ActionsReport
CROSS APPLY
(
SELECT CAST(REGION AS VARCHAR(50)) UNION ALL
SELECT CAST(STATE_ABBR AS VARCHAR(50)) UNION ALL
SELECT CAST([Status] AS VARCHAR(50))
) c(col)
) x
PIVOT
(
COUNT(MitigationActionID)
FOR EntryDate IN (' + @cols + ')
) p ';
EXECUTE(@query);
출력은 다음과 같아야합니다
+-REGION-+-STATE_ABBR-+-Status------+-11_2012-+-4_2013-+-6_2013-+-11_2013-+
| 01 | CT | Identified | 1 | 1 | 1 | 1 |
| 01 | CT | In Progress | 1 | 0 | 0 | 0 |
위의 쿼리의 주석에 위와 같은 내용을 포함시키지 않으면 출력 테이블의 1이 모두 3이됩니다. CROSS APPLY의 SELECTS 수를 변경하면 총계가 같은 방식으로 변경되기 때문에 CROSS APPLY에서 오는 것이 확실합니다.
나는 이것을 할 수있는 더 좋은 방법이있을 것이라고 확신하지만 실패했습니다. 나는 DISTINCT를 작동시키려는 데 꽤 많은 시간을 보냈지 만 PIVOT 내에서 COUNT DISTINCT가 작동하지 않는 것처럼 보였습니다.
누구든지 내게이 문제에 대해 조언을 해줄 수 있다면 크게 감사하겠습니다.
'COUNT (DISTINCT MitigationActionID)'는 작동합니까? – NickyvV
@NickyvV, 아니요, 나는 그 일을하기 위해 많은 시간을 보냈지 만 해결책을 찾지 못했습니다. 'DISTINCT '키워드 근처에'잘못된 구문이 나타납니다 .' – Matthew