簡體   English   中英

從日期中的行中導出列名,並在sql中顯示每月數據

[英]Derive column name from date in rows and show monthly data in sql

我有一個如下表:

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比較陌生。 提前致謝

嘗試這個..

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

旋轉時

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都在一列中,然后我們在GROUP BYORDER BY的幫助下使用PIVOT獲得所需的結果。

如果有很多Vals最好使用動態SQL。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM