是否可以采用以下列方式构建的表:
ID Month Info1 Info2
1 1 A B
1 2 C D
1 3 E F
2 3 G H
2 4 I J
最终会变成这样的表:
ID JanInfo1 JanInfo2 FebInfo1 FebInfo2 MarInfo1 MarInfo2 AprInfo1 AprInfo2
1 A B C D E F NULL NULL
2 NULL NULL NULL NULL G H I J
我已经研究过使用枢轴并且无法让它们工作。
我目前每个月都使用CROSS APPLY表值函数。
有更好的方法吗?
编辑:添加现有查询 - 尝试简化显示:
-- Get the unique IDs
DECLARE @PersonIds TABLE
(
UploadID UNIQUEIDENTIFIER,
PersonId VARCHAR(200),
RecordYear INT
)
INSERT INTO @PersonIds
SELECT DISTINCT UploadID, PersonId, RecordYear
FROM [VERTICALTABLE]
WHERE UploadID = @PTPUploadID
AND RecordYear = @RecordYear
GROUP BY UploadID, PersonId, RecordYear
-- Flatten via functions
INSERT INTO [FLATTABLE](PersonID, JanuaryCoverage, FebruaryCoverage, MarchCoverage, AprilCoverage, MayCoverage, JuneCoverage,
JulyCoverage, AugustCoverage, SeptemberCoverage, OctoberCoverage, NovemberCoverage, DecemberCoverage)
SELECT PID.PersonID, M1.Covered, M2.Covered, M3.Covered, M4.Covered, M5.Covered, M6.Covered,
M7.Covered, M8.Covered, M9.Covered, M10.Covered, M11.Covered, M12.Covered
FROM @PersonIds AS PID
OUTER APPLY GetMonthInfpo(@PTPUploadID, @RecordYear, 1, PID.PersonId) AS M1
OUTER APPLY GetMonthInfpo(@PTPUploadID, @RecordYear, 2, PID.PersonId) AS M2
OUTER APPLY GetMonthInfpo(@PTPUploadID, @RecordYear, 3, PID.PersonId) AS M3
OUTER APPLY GetMonthInfpo(@PTPUploadID, @RecordYear, 4, PID.PersonId) AS M4
OUTER APPLY GetMonthInfpo(@PTPUploadID, @RecordYear, 5, PID.PersonId) AS M5
OUTER APPLY GetMonthInfpo(@PTPUploadID, @RecordYear, 6, PID.PersonId) AS M6
OUTER APPLY GetMonthInfpo(@PTPUploadID, @RecordYear, 7, PID.PersonId) AS M7
OUTER APPLY GetMonthInfpo(@PTPUploadID, @RecordYear, 8, PID.PersonId) AS M8
OUTER APPLY GetMonthInfpo(@PTPUploadID, @RecordYear, 9, PID.PersonId) AS M9
OUTER APPLY GetMonthInfpo(@PTPUploadID, @RecordYear, 10, PID.PersonId) AS M10
OUTER APPLY GetMonthInfpo(@PTPUploadID, @RecordYear, 11, PID.PersonId) AS M11
OUTER APPLY GetMonthInfpo(@PTPUploadID, @RecordYear, 12, PID.PersonId) AS M12
WHERE UploadID = @PTPUploadID
AND RecordYear = @RecordYear
功能看起来像
ALTER FUNCTION GetMonthInfpo(
(
@UploadID UNIQUEIDENTIFIER,
@Year INT,
@Month INT,
@PersonID VARCHAR(200)
)
RETURNS TABLE
AS
RETURN
(
SELECT COUNT(*) AS 'Covered'
FROM [VERTICALTABLE]
WHERE UploadID = @UploadID
AND RecordYear = @Year
AND RecordMonth = @Month
AND PersonId = @PersonID
)
答案 0 :(得分:2)
您不需要多个子项。答案很简单 - 使用集合论。从您的第一个表ID /月/ Info1 / Info2做ID /月+(1 + 2)/信息与简单联合 - 例如:
select ID, cast(Month as varchar(10)) + cast('_1' as varchar(10)) ComposedMonth, Info1 Info
from tbl
union all
select ID, cast(Month as varchar(10)) + cast('_2' as varchar(10)), Info2
from tbl
然后使用此数据集(显示为视图或临时表)pivot
子句。
select *
from vw_tbl t
pivot (max(Info) for ComposedMonth in ([1_1], [1_2]...)) p
-- or if you will cast month to text
-- pivot (max(Info) for ComposedMonth in ([Jan_1], [Jan_2]...)) p
组合字符串是轻松转动的关键。
答案 1 :(得分:1)
使用更新的信息
SELECT
t.PersonID,
JanuaryCoverage = SUM(CASE WHEN t.RecordMonth = 1 THEN Info1 ELSE 0 END),
FebruaryCoverage = SUM(CASE WHEN t.RecordMonth = 2 THEN Info1 ELSE 0 END),
MarchCoverage = SUM(CASE WHEN t.RecordMonth = 3 THEN Info1 ELSE 0 END),
AprilCoverage = SUM(CASE WHEN t.RecordMonth = 4 THEN Info1 ELSE 0 END),
MayCoverage = SUM(CASE WHEN t.RecordMonth = 5 THEN Info1 ELSE 0 END),
JuneCoverage = SUM(CASE WHEN t.RecordMonth = 6 THEN Info1 ELSE 0 END),
JulyCoverage = SUM(CASE WHEN t.RecordMonth = 7 THEN Info1 ELSE 0 END),
AugustCoverage = SUM(CASE WHEN t.RecordMonth = 8 THEN Info1 ELSE 0 END),
SeptemberCoverage = SUM(CASE WHEN t.RecordMonth = 9 THEN Info1 ELSE 0 END),
OctoberCoverage = SUM(CASE WHEN t.RecordMonth = 10 THEN Info1 ELSE 0 END),
NovemberCoverage = SUM(CASE WHEN t.RecordMonth = 11 THEN Info1 ELSE 0 END),
DecemberCoverage = SUM(CASE WHEN t.RecordMonth = 12 THEN Info2 ELSE 0 END)
FROM [VERTICALTABLE] t
WHERE
t.UploadID = @UploadID
AND RecordYear = @Year
GROUP BY t.PersonId;
使用条件聚合:
SELECT
t.ID,
JanInfo1 = MAX(CASE WHEN t.[Month] = 1 THEN Info1 END),
JanInfo2 = MAX(CASE WHEN t.[Month] = 1 THEN Info2 END),
FebInfo1 = MAX(CASE WHEN t.[Month] = 2 THEN Info1 END),
FebInfo2 = MAX(CASE WHEN t.[Month] = 2 THEN Info2 END),
MarInfo1 = MAX(CASE WHEN t.[Month] = 3 THEN Info1 END),
MarInfo2 = MAX(CASE WHEN t.[Month] = 3 THEN Info2 END),
AprInfo1 = MAX(CASE WHEN t.[Month] = 4 THEN Info1 END),
AprInfo2 = MAX(CASE WHEN t.[Month] = 4 THEN Info2 END),
MayInfo1 = MAX(CASE WHEN t.[Month] = 5 THEN Info1 END),
MayInfo2 = MAX(CASE WHEN t.[Month] = 5 THEN Info2 END),
JunInfo1 = MAX(CASE WHEN t.[Month] = 6 THEN Info1 END),
JunInfo2 = MAX(CASE WHEN t.[Month] = 6 THEN Info2 END),
JulInfo1 = MAX(CASE WHEN t.[Month] = 7 THEN Info1 END),
JulInfo2 = MAX(CASE WHEN t.[Month] = 7 THEN Info2 END),
AugInfo1 = MAX(CASE WHEN t.[Month] = 8 THEN Info1 END),
AugInfo2 = MAX(CASE WHEN t.[Month] = 8 THEN Info2 END),
SepInfo1 = MAX(CASE WHEN t.[Month] = 9 THEN Info1 END),
SepInfo2 = MAX(CASE WHEN t.[Month] = 9 THEN Info2 END),
OctInfo1 = MAX(CASE WHEN t.[Month] = 10 THEN Info1 END),
OctInfo2 = MAX(CASE WHEN t.[Month] = 10 THEN Info2 END),
NovInfo1 = MAX(CASE WHEN t.[Month] = 11 THEN Info1 END),
NovInfo2 = MAX(CASE WHEN t.[Month] = 11 THEN Info2 END),
DecInfo1 = MAX(CASE WHEN t.[Month] = 12 THEN Info1 END),
DecInfo2 = MAX(CASE WHEN t.[Month] = 12 THEN Info2 END)
FROM Tbl t
GROUP BY t.ID;