sql >> Databasteknik >  >> RDS >> Sqlserver

sql-fråga för att dynamiskt lägga till räkenskapsmånad med pivot

Du måste använda dynamisk SQL för att göra detta. Den grova koden kommer att likna denna:

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)

Mitt förslag istället för att använda temptabellen @FiscalMonth är att skapa en tabell som är permanent för detta. Det kommer att vara mycket enklare att fråga mot en perm-tabell snarare än temp-tabellen när du använder dynamisk sql. Temp-tabellen kan vara utanför räckvidden för den dynamiska frågan.



  1. Finns det någon skillnad mellan varchar(10) och varchar(1000) när vi lagrar en sträng vars längd är mindre än 10?

  2. Ändra NULLs position i sortering

  3. Partitioneringstabell baserad på första bokstaven i ett varchar-fält

  4. Rangordna användare i mysql efter deras poäng