我有一张如下表:
CREATE table #yourtable
(
[Id] int,
[ColumnName] varchar(13),
Val1 float,
Val2 float,
StartDate datetime,
EndDate datetime
);
INSERT INTO #yourtable
([Id], [ColumnName],Val1,Val2,StartDate,EndDate)
VALUES
(1,'ABC12',1000,900,'2016-01-01 00:00:00','2016-01-31 23:59:59'),
(2,'ABC12',1100,900,'2016-02-01 00:00:00','2016-02-29 23:59:59'),
(3,'CDE34',1000,800,'2016-01-01 00:00:00','2016-01-31 23:59:59'),
(4,'EFG45',1000,700,'2016-03-01 00:00:00','2016-03-31 23:59:59'),
(5,'FGH56',1000,1001,'2016-02-01 00:00:00','2016-02-29 23:59:59');
我试图获得如下的月度隔离数据:
Column Name Jan Feb Mar
ABC12 1000 1100 null
ABC12 900 900 null
CDE34 1000 null null
CDE34 800 null null
EFG45 null null 1000
EFG45 null null 700
FGH56 null 1000 null
FGH56 null 1001 null
我对sql相对较新。 提前致谢
答案 0 :(得分:1)
试试这个..
SELECT * FROM (SELECT [ColumnName],
SUM(Val1) AS _Val,
CONVERT(VARCHAR(3), DATENAME(MONTH, DATEADD(MONTH, MONTH(StartDate), - 1))) MonthCol
FROM #yourtable WHERE YEAR(StartDate) = 2016
GROUP BY StartDate,[ColumnName]) AS TP
PIVOT (SUM(_Val) FOR MonthCol IN ([Jan], [Feb], [Mar], [Apr], [May], [Jun], [Jul], [Aug], [Sep], [Oct], [Nov], [Dec])) AS PVTTable
UNION
SELECT * FROM (SELECT [ColumnName],
SUM(Val2) AS _Val,
CONVERT(VARCHAR(3), DATENAME(MONTH, DATEADD(MONTH, MONTH(EndDate), - 1))) MonthCol
FROM #yourtable WHERE YEAR(EndDate) = 2016
GROUP BY EndDate,[ColumnName]) AS TP
PIVOT (SUM(_Val) FOR MonthCol IN ([Jan], [Feb], [Mar], [Apr], [May], [Jun], [Jul], [Aug], [Sep], [Oct], [Nov], [Dec])) AS PVTTable
用于动态查询
DECLARE @MaxMonth DATE = GETDATE();
DECLARE @YearData NVARCHAR(4) = CAST(YEAR(@MaxMonth) AS NVARCHAR(4))
DECLARE @END_MM INT = MONTH(@MaxMonth) --End of Month
DECLARE @START_MM INT = 1 --Start Month of Year Data
DECLARE @TB_DATE AS TABLE
(
ID INT IDENTITY(1,1),
MONTH_LIST VARCHAR(12)
)
WHILE @START_MM <= @END_MM
BEGIN
INSERT INTO @TB_DATE (MONTH_LIST) VALUES ('['+CONVERT(VARCHAR(3),DATENAME(MONTH, DATEADD(MONTH, @START_MM-1, CAST(@END_MM AS datetime))))+']')
SET @START_MM=@START_MM+1
END
DECLARE @MM_LIST NVARCHAR(MAX) = (SELECT STUFF((SELECT ',' + MONTH_LIST
FROM @TB_DATE ORDER BY ID DESC
FOR XML PATH('')) ,1,1,'') AS Txt)
DECLARE @DynamicPivot AS NVARCHAR(MAX)
SET @DynamicPivot = N' SELECT * FROM (SELECT [ColumnName],
SUM(Val1) AS _Val,
CONVERT(VARCHAR(3), DATENAME(MONTH, DATEADD(MONTH, MONTH(StartDate), - 1))) MonthCol
FROM #yourtable WHERE YEAR(StartDate) = '+@YearData+'
GROUP BY StartDate,[ColumnName]) AS TP
PIVOT (SUM(_Val) FOR MonthCol IN ('+@MM_LIST+')) AS PVTTable
UNION
SELECT * FROM (SELECT [ColumnName],
SUM(Val2) AS _Val,
CONVERT(VARCHAR(3), DATENAME(MONTH, DATEADD(MONTH, MONTH(EndDate), - 1))) MonthCol
FROM #yourtable WHERE YEAR(EndDate) = '+@YearData+'
GROUP BY EndDate,[ColumnName]) AS TP
PIVOT (SUM(_Val) FOR MonthCol IN ('+@MM_LIST+')) AS PVTTable';
EXEC sp_executesql @DynamicPivot
答案 1 :(得分:1)
使用pivoting:
SELECT ColumnName,
MAX([Jan]) as [Jan],
MAX([Feb]) as [Feb],
MAX([Mar]) as [Mar],
MAX([Apr]) as [Apr],
MAX([May]) as [May],
MAX([Jun]) as [Jun],
MAX([Jul]) as [Jul],
MAX([Aug]) as [Aug]
FROM (
SELECT Id,
ColumnName,
LEFT(DATENAME(MONTH,StartDate),3) as M,
[Vals],
[Column]
FROM
(SELECT *
FROM #yourtable) y
UNPIVOT (
[Column] FOR Vals IN ([Val1],[Val2])
)as unpvt
) as s
PIVOT (
MAX([Column]) FOR M IN ([Jan],[Feb],[Mar],[Apr],[May],[Jun],[Jul],[Aug])
) as pvt
GROUP BY ColumnName,Vals
ORDER BY ColumnName
输出:
ColumnName Jan Feb Mar
ABC12 1000 1100 NULL
ABC12 900 900 NULL
CDE34 1000 NULL NULL
CDE34 800 NULL NULL
EFG45 NULL NULL 1000
EFG45 NULL NULL 700
FGH56 NULL 1000 NULL
FGH56 NULL 1001 NULL
使用UNPIVOT,我们得到了这个表结构:
Id ColumnName M Vals Column
1 ABC12 Jan Val1 1000
1 ABC12 Jan Val2 900
2 ABC12 Feb Val1 1100
2 ABC12 Feb Val2 900
3 CDE34 Jan Val1 1000
3 CDE34 Jan Val2 800
4 EFG45 Mar Val1 1000
4 EFG45 Mar Val2 700
5 FGH56 Feb Val1 1000
5 FGH56 Feb Val2 1001
因此,所有Vals
都在一列中,然后我们使用PIVOT在GROUP BY和ORDER BY的帮助下获得所需的结果。
如果有许多Vals
更好地使用动态SQL。