以动态SQL作为参数进行数据透视

时间:2018-08-28 07:38:23

标签: sql-server tsql stored-procedures

我不确定这是否可行,但我想知道是否有某种方式可以使用存储过程并传递查询以使值旋转。我不确定这是否是个好主意,如果这是一个愚蠢的问题,则感到抱歉,但是最好传递一个查询,而不是对您想要的每个枢轴进行硬编码。我有一个我编写的数据透视存储过程的例子。这还包括行和列的总计。

不知道我是否也应该添加代码?

希望这很有道理。

请在下面查看我的存储过程代码:

CREATE PROCEDURE [dbo].[PivotNoAgentPerc_SP]
AS

DECLARE @columnHeaders VARCHAR (MAX)

SELECT @columnHeaders  = COALESCE(@columnHeaders + ', ','')+ QUOTENAME(granteddate)
FROM
(
    SELECT DISTINCT EOMONTH(BondSales.granteddate,0) AS granteddate

                    FROM  ccbsm_ccbsm_salemanagement AS BondSales
                    LEFT OUTER JOIN ccbsm_ccbsm_salemanagement_cstm AS BondSalesCSTM ON BondSales.id = BondSalesCSTM.id_c 
                    LEFT OUTER JOIN CapcubedInternalDB.dbo.ProvincialArea AS ProvincialArea ON BondSalesCstm.provincial_level_c = ProvincialArea.ID
                    LEFT OUTER JOIN accounts AS accounts_1 ON BondSales.account_id1_c = accounts_1.id  AND accounts_1.deleted = 0
                    LEFT OUTER JOIN users AS ConsultantUser ON BondSales.Assigned_user_id = ConsultantUser.id  AND ConsultantUser.deleted = 0

                    LEFT OUTER JOIN CapcubedInternalDB.dbo.BondSaleApplicationStatus AS BondSalesStatus ON BondSalesStatus.ID = BondSales.applicationstatus

                    WHERE BondSales.deleted = 0

                    AND ProvincialArea.SAD_Province = 'Coastal'
                    AND BondSalesStatus.AuditedStatus = 1
                    AND EOMONTH(BondSales.granteddate,0) BETWEEN EOMONTH(GETDATE(),-12) AND EOMONTH(GETDATE(),-1)
) AS B
ORDER BY B.granteddate

/* GRAND TOTAL COLUMN */
DECLARE @GrandTotalCol  NVARCHAR (MAX)

SELECT @GrandTotalCol =
COALESCE (@GrandTotalCol + 'ISNULL ([' + CAST (granteddate AS VARCHAR) +'],0) + ', 'ISNULL([' + CAST(granteddate AS VARCHAR)+ '],0) + ')
FROM
(
    SELECT DISTINCT EOMONTH(BondSales.granteddate,0) AS granteddate

                    FROM  ccbsm_ccbsm_salemanagement AS BondSales
                    LEFT OUTER JOIN ccbsm_ccbsm_salemanagement_cstm AS BondSalesCSTM ON BondSales.id = BondSalesCSTM.id_c 
                    LEFT OUTER JOIN CapcubedInternalDB.dbo.ProvincialArea AS ProvincialArea ON BondSalesCstm.provincial_level_c = ProvincialArea.ID
                    LEFT OUTER JOIN accounts AS accounts_1 ON BondSales.account_id1_c = accounts_1.id  AND accounts_1.deleted = 0
                    LEFT OUTER JOIN users AS ConsultantUser ON BondSales.Assigned_user_id = ConsultantUser.id  AND ConsultantUser.deleted = 0

                    LEFT OUTER JOIN CapcubedInternalDB.dbo.BondSaleApplicationStatus AS BondSalesStatus ON BondSalesStatus.ID = BondSales.applicationstatus

                    WHERE BondSales.deleted = 0

                    AND ProvincialArea.SAD_Province = 'Coastal'
                    AND BondSalesStatus.AuditedStatus = 1
                    AND EOMONTH(BondSales.granteddate,0) BETWEEN EOMONTH(GETDATE(),-12) AND EOMONTH(GETDATE(),-1)
) AS B
ORDER BY B.granteddate
SET @GrandTotalCol = LEFT (@GrandTotalCol, LEN (@GrandTotalCol)-1)

/* GRAND TOTAL ROW */
DECLARE @GrandTotalRow  NVARCHAR(MAX)

SELECT @GrandTotalRow = 
COALESCE(@GrandTotalRow + ',ISNULL(SUM([' + CAST(granteddate AS VARCHAR)+']),0)', 'ISNULL(SUM([' + CAST(granteddate AS VARCHAR)+']),0)')
FROM
(
    SELECT DISTINCT EOMONTH(BondSales.granteddate,0) AS granteddate

                    FROM  ccbsm_ccbsm_salemanagement AS BondSales
                    LEFT OUTER JOIN ccbsm_ccbsm_salemanagement_cstm AS BondSalesCSTM ON BondSales.id = BondSalesCSTM.id_c 
                    LEFT OUTER JOIN CapcubedInternalDB.dbo.ProvincialArea AS ProvincialArea ON BondSalesCstm.provincial_level_c = ProvincialArea.ID
                    LEFT OUTER JOIN accounts AS accounts_1 ON BondSales.account_id1_c = accounts_1.id  AND accounts_1.deleted = 0
                    LEFT OUTER JOIN users AS ConsultantUser ON BondSales.Assigned_user_id = ConsultantUser.id  AND ConsultantUser.deleted = 0

                    LEFT OUTER JOIN CapcubedInternalDB.dbo.BondSaleApplicationStatus AS BondSalesStatus ON BondSalesStatus.ID = BondSales.applicationstatus

                    WHERE BondSales.deleted = 0

                    AND ProvincialArea.SAD_Province = 'Coastal'
                    AND BondSalesStatus.AuditedStatus = 1
                    AND EOMONTH(BondSales.granteddate,0) BETWEEN EOMONTH(GETDATE(),-12) AND EOMONTH(GETDATE(),-1)
)AS B
ORDER BY B.granteddate

/* MAIN QUERY */
DECLARE @FinalQuery NVARCHAR (MAX)
SET @FinalQuery =   'SELECT *, ('+ @GrandTotalCol + ')
AS [Grand Total] INTO #temp_MatchesTotal
            FROM
                (SELECT
                    ISNULL(ConsultantUser.user_name,''Total'') AS [Consultant],
                    EOMONTH(BondSales.granteddate,0) AS [Month Granted],
                    COALESCE(CAST(CAST(SUM(CASE WHEN accounts_1.name = ''No Agent Channel'' THEN 1 ELSE 0 END) AS DECIMAL)/COUNT(BondSales.name) AS decimal(5,2)), 0) AS NoAgentPerc

                    FROM  ccbsm_ccbsm_salemanagement AS BondSales
                    LEFT OUTER JOIN ccbsm_ccbsm_salemanagement_cstm AS BondSalesCSTM ON BondSales.id = BondSalesCSTM.id_c 
                    LEFT OUTER JOIN CapcubedInternalDB.dbo.ProvincialArea AS ProvincialArea ON BondSalesCstm.provincial_level_c = ProvincialArea.ID
                    LEFT OUTER JOIN accounts AS accounts_1 ON BondSales.account_id1_c = accounts_1.id  AND accounts_1.deleted = 0
                    LEFT OUTER JOIN users AS ConsultantUser ON BondSales.Assigned_user_id = ConsultantUser.id  AND ConsultantUser.deleted = 0

                    LEFT OUTER JOIN CapcubedInternalDB.dbo.BondSaleApplicationStatus AS BondSalesStatus ON BondSalesStatus.ID = BondSales.applicationstatus

                    WHERE BondSales.deleted = 0

                    AND ProvincialArea.SAD_Province = ''Coastal''
                    AND BondSalesStatus.AuditedStatus = 1
                    AND EOMONTH(BondSales.granteddate,0) BETWEEN EOMONTH(GETDATE(),-12) AND EOMONTH(GETDATE(),-1)

                    GROUP BY EOMONTH(BondSales.granteddate, 0), ConsultantUser.user_name
                ) A
            PIVOT
                (
                 SUM(NoAgentPerc)
                 FOR [Month Granted]
                 IN ('+@columnHeaders +')
                ) B
ORDER BY [Consultant]

SELECT * FROM #temp_MatchesTotal

UNION ALL

SELECT ''Grand Total'','+ @GrandTotalRow +', ISNULL (SUM([Grand Total]),0)
FROM #temp_MatchesTotal
DROP TABLE #temp_MatchesTotal'

EXECUTE(@FinalQuery)

很抱歉,如果代码很长,但是我只是想向您展示我在说什么

1 个答案:

答案 0 :(得分:0)

我已经按照程序进行了,并且工作正常。将您的示例与以下代码进行比较

您必须编写动态sql查询 示例:

  declare @s date 

   declare @e date 

   declare @dates varchar(MAX) 





   set @s=DATEADD(DAY,-1,@startdate)

   set @e=@enddate



   IF OBJECT_ID('tempdb.#DATES') IS NOT NULL  

     DROP TABLE #DATES





   CREATE TABLE #DATES

   (

          ID INT PRIMARY KEY IDENTITY(1,1),

          Date VARCHAR(MAX)

   )



   WHILE (@s<@e)

   BEGIN

          INSERT INTO #DATES (Date) 

          select  CONCAT( '[',DATEADD(DAY ,1, @s),']')

          set @s=DATEADD(DAY ,1, @s)

   END



   SELECT @dates= STUFF((

          SELECT ',' + SPACE(1) + Date



 FROM #DATES

          FOR XML PATH(''), TYPE).value('.', 'VARCHAR(MAX)'), 1, 1, '')

          --AS [Dates]



   ------------------------Getting RDW Datewise--------------------------------------

   declare @queryRDW VARCHAR(MAX)

   set @queryRDW='

   select * from (

                 SELECT SUM(RecordValue)/60 RecordValue,RecordType ,Computationdate ,t2.ProjectResourceId,t1.ResourceCode,t1.ResourceName

                 FROM   tblProjectResource t1 INNER JOIN  tblDeploymentWorkbook t2 on t1.ProjectResourceId=t2.ProjectResourceId

                 WHERE 

                        RecordType=''RDW'' and t2.SubCategoryId IN (1) 

                 GROUP BY 

                       RecordType, Computationdate,t2.ProjectResourceId,t1.resourceCode,t1.ResourceName

                 HAVING 

                       Computationdate >= '''+Cast(@startdate as varchar)+''' and Computationdate <= '''+Cast(@enddate as varchar)+'''

   )tab

   PIVOT(

          SUM(RecordValue) for ComputationDate in  ( '+@dates+')

   )t

   Order By ResourceName

   '

   exec (@queryRDW)