sql >> データベース >  >> RDS >> Sqlserver

ピボットを使用して会計月を動的に追加するSQLクエリ

    これを行うには、動的 SQL を使用する必要があります。 ラフ コードは次のようになります:

    ALTER PROCEDURE [dbo].[_sp_GetDMActivityTrackerReport]
        @CoachId VARCHAR(7),
        @Month INT,
        @FiscalYear INT
    AS 
    BEGIN    
    
    INSERT @FiscalMonth (ID,Month,NbHolidays,MonthDate,TotalDays)
    EXECUTE dbo._sp_GetFiscalMonths @Month, @FiscalYear
    
    DECLARE @cols AS NVARCHAR(MAX),
        @colsNull AS NVARCHAR(MAX),
        @colsSum AS NVARCHAR(MAX),
        @query  AS NVARCHAR(MAX)
    
    select @cols = STUFF((SELECT distinct ',' + QUOTENAME(DateName(Month,nft.MonthPeriodStart)) 
                        from NonFieldTime nft
                        where datename(Month,nft.MonthPeriodStart) + '-'+ substring(datename(Year,nft.MonthPeriodStart),3,2) 
                            IN (SELECT Month +'-' +substring(datename(Year,MonthDate),3,2) [Months] 
                                FROM [email protected])
                FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),1,1,'')
    
    select @colsNull = STUFF((SELECT distinct ', IsNull(' + QUOTENAME(DateName(Month,nft.MonthPeriodStart))+', 0) as '+DateName(Month,nft.MonthPeriodStart)
                        from NonFieldTime nft
                        where datename(Month,nft.MonthPeriodStart) + '-'+ substring(datename(Year,nft.MonthPeriodStart),3,2) 
                            IN (SELECT Month +'-' +substring(datename(Year,MonthDate),3,2) [Months] 
                                FROM [email protected])
                FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)') ,1,1,'')
    
    select @colsSum = STUFF((SELECT distinct '+ IsNull(' + QUOTENAME(DateName(Month,nft.MonthPeriodStart))+', 0)'
                        from NonFieldTime nft
                        where datename(Month,nft.MonthPeriodStart) + '-'+ substring(datename(Year,nft.MonthPeriodStart),3,2) 
                            IN (SELECT Month +'-' +substring(datename(Year,MonthDate),3,2) [Months] 
                                FROM [email protected])
                FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)') ,1,1,'')+' as [Total Field TIME] '
    
    set @query = 'SELECT PreparationID,CoachId,UserID, MemberID,
                        [Rep Name], ' + @colsNull + ', '+ @colsSum+' 
                 from 
                 (
                    SELECT up.PreparationID,
                        tt.UserId [CoachId],
                        up.UserID, utm.MemberID, 
                        (ui.FirstName + '' '' + ui.LastName) AS [Rep Name],
                        DateName(Month,nft.MonthPeriodStart) [Month], 
                        sum(nft.Quantity) [Days]
                    FROM TransferedTime tt
                    INNER JOIN UPreparation up 
                        ON tt.PreparationID = up.PreparationID 
                    RIGHT JOIN UTeamMembers utm 
                        ON tt.UserId = utm.CoachID AND utm.MemberID = up.UserID
                    INNER JOIN UserInfo ui 
                        ON utm.MemberID = ui.UserID
                    LEFT JOIN NonFieldTime nft 
                        ON nft.UserId = tt.UserId 
                        AND tt.MonthPeriodFrom = nft.MonthPeriodStart
                        AND datename(Month,nft.MonthPeriodStart) + ''-''+ substring(datename(Year,nft.MonthPeriodStart),3,2) IN 
                            (SELECT Month +''-'' +substring(datename(Year,MonthDate),3,2) [Months] 
                             FROM [email protected])
                    WHERE utm.MemberID IN (SELECT MemberID 
                                            FROM UTeamMembers 
                                            WHERE CoachID = '[email protected]+')
                    GROUP BY up.PreparationID,tt.UserId,up.UserID, utm.MemberID,
                    (ui.FirstName + '' '' + ui.LastName),DateName(Month,nft.MonthPeriodStart)
                ) x
                pivot 
                (
                    sum(Days)
                    for Month in (' + @cols + ')
                ) p '
    
    execute(@query)
      

    一時テーブル @FiscalMonth を使用する代わりに私の提案 このために永続的なテーブルを作成することです。動的 SQL を使用する場合は、一時テーブルではなく永続テーブルに対してクエリを実行する方がはるかに簡単です。一時テーブルが動的クエリの範囲外である可能性があります。



    1. Postgresは、行数が制限を下回っている場合にのみ行を挿入します

    2. 複雑なクエリで2つのテーブルを結合する(均一なデータではない)

    3. エイリアスでのHAVINGとHAVINGを使用しない場合のパフォーマンスの違いはありますか?

    4. JPAおよびJSON演算子のネイティブクエリ