【问题标题】:Dynamically Creating Columns for an Unknown # of Columns为未知的列数动态创建列
【发布时间】:2015-05-03 02:32:52
【问题描述】:

我希望完成的是在存储过程中根据需要动态创建列。我的问题在于驱动器可能没有激励,1 个激励或多个(2,3,4.etc)激励分配给驱动器。下面是示例数据的屏幕截图:

我最初使用 FOR XML 路径来连接记录:

Stuff ((Select ', ' + isnull(EM.Description,'')
    From EquipmentMaster EM
        Inner Join EquipmentDetail ED On EM.EquipmentID = ED.EquipmentID And EM.EquipmentType=3
        Where ED.DriveID = DM.DriveID
            For XML PATH(''), TYPE).value('.', 'varchar(max)')
            ,1, 2, '') as [Incentives]

但最终用户已要求将激励措施放在单独的列中。我正在尝试重用我在这里找到的一些代码:Stack Overflow link

但我无法让它工作。希望获得一些帮助以使此程序正常运行。

这是程序代码:

declare
@startDate datetime,
@endDate datetime,
@RegID varchar(8000),
@OrgID varchar(8000),
@SubID varchar(8000),
@COID varchar(8000),
@RecID varchar(8000),
@StatusID varchar(8000),
@Cols nvarchar(max),
@Incentives nvarchar(max)

Select @Cols = Stuff ((Select ', ' + isnull(EM.Description,'')
            From EquipmentMaster EM
            Inner Join EquipmentDetail ED On EM.EquipmentID = ED.EquipmentID And EM.EquipmentType=3
            --Where ED.DriveID = DM.DriveID
            For XML PATH(''), TYPE).value('.', 'varchar(max)')
            ,1, 2, '')

Select
DM.DriveID [DriveID],
DM.FromDateTime [FromDateTime],
Case When DM.OwnerType = 0 Then Acct.Name Else CD.DescLong End As [OwnerName],

Stuff ((Select ', ' + isnull(EM.Description,'')
    From EquipmentMaster EM
        Inner Join EquipmentDetail ED On EM.EquipmentID = ED.EquipmentID And EM.EquipmentType=3
        Where ED.DriveID = DM.DriveID
            For XML PATH(''), TYPE).value('.', 'varchar(max)')
            ,1, 2, '') as [Incentives]
From
rpt_DriveMaster DM
Left Outer Join rpt_Accounts Acct on DM.AccountID=Acct.AccountID
Left Outer Join IDViewRecruiters Rec on Acct.RecruiterID=Rec.CodeID
Inner Join rpt_CenterDetail CD on DM.CenterID=CD.CenterID

Where
DM.StatusID <>5
And DM.FromDateTime Between '03/01/2015' AND '03/02/2015'

这是我的原始程序,它将所有激励措施集中在一个列中(SSRS 使用它来显示报告):

Create Procedure Hema_IncentiveReport
@startDate datetime,
@endDate datetime,
@RegID varchar(8000),
@OrgID varchar(8000),
@SubID varchar(8000),
@COID varchar(8000),
@RecID varchar(8000),
@StatusID varchar(8000)

As

Begin

Select Item Into #Region From OBAPPS.[dbo].DelimitedSplit8K(@RegID,',');
Select Item Into #OrgCenter From OBAPPS.[dbo].DelimitedSplit8k(@OrgID,',');
Select Item Into #SubCenter From OBAPPS.[dbo].DelimitedSplit8k(@SubID,',');
Select Item Into #CollectionOp From OBAPPS.[dbo].DelimitedSplit8k(@COID,',');
Select Item Into #Recruiter From OBAPPS.[dbo].DelimitedSplit8k(@RecID,',');
Select Item Into #DriveStatus From OBAPPS.[dbo].DelimitedSplit8k(@StatusID,',');

Select
DM.DriveID [DriveID],
DM.FromDateTime [FromDateTime],
Case When DM.OpenToPublic = 1 Then 'Yes' Else 'No' End As [OpenToPublic],
Case When DM.OwnerType=0 Then 'Mobile' Else 'Fixed' End As [OwnerType],
Case When DM.OwnerType = 0 Then Acct.Name Else CD.DescLong End As [OwnerName],
DT.EarlyShiftStart [EarlyShiftStart],
DT.LateShiftEnd [LateShiftEnd],
DrStat.StatusText [DriveStatus],
Acct.AccountID [AcctID],
Acct.InternalName [AcctInternalName],
Acct.ExternalID [ExternalID],
AD.Addr1 [Addr1],
AD.Addr2 [Addr2],
AD.City [City],
AD.State [State],
AD.Zip [Zip],
CO.CodeID [CO_ID],
CO.Description [CO_Desc],
Org.CodeID [Org_ID],
Org.Description [Org_Desc],
Rec.CodeID [Rec_ID],
Rec.Description [Rec_Desc],
Sub.CodeID [Sub_ID],
Sub.Description [Sub_Desc],
Reg.CodeID [Reg_ID],
Reg.Description [Reg_Desc],
DPaCT.ProcedureProjection [Proc_Proj],
DPaCT.ProductProjection [Prod_Proj],
DPaCT.ProceduresPerformed [Proc_Perf],
DPaCT.ProductsCollected [Prod_Coll],
DPaCT.QNS [QNS],
DPaCT.FTD [FTD],
(isnull(DPaCT.ProductsCollected,0))-(isnull(DPaCT.ProceduresPerformed,0)) [Alyx],

Stuff ((Select Distinct ', ' + isnull(MSM.ShortDesc,'')
    From Production.[dbo].rpt_DriveShiftDetail DSD
        Inner Join Production.[dbo].rpt_DriveShiftMobileDetail DSMD On DSMD.ShiftID = DSD.ShiftID
        Inner Join Production.[dbo].rpt_MobileSetupMaster MSM 
            On MSM.MobileType = 1 and MSM.MobileID = DSMD.MobileID
            Where DSD.DriveID = DM.DriveID
            For XML PATH(''), TYPE).value('.', 'varchar(max)')
            ,1, 2, '') as [Mobile_Short_Desc],

Stuff ((Select ', ' + isnull(EM.Description,'')
    From Production.[dbo].EquipmentMaster EM
        Inner Join Production.[dbo].EquipmentDetail ED On EM.EquipmentID = ED.EquipmentID And EM.EquipmentType=3
        Where ED.DriveID = DM.DriveID
            For XML PATH(''), TYPE).value('.', 'varchar(max)')
            ,1, 2, '') as [Incentives]

From
Production.[dbo].rpt_DriveMaster DM
Left Outer Join Production.[dbo].rpt_Accounts Acct on DM.AccountID=Acct.AccountID
Inner Join Production.[dbo].DriveTimes DT on DM.DriveID=DT.DriveID
Left Outer Join Production.[dbo].rpt_AddressDetail AD on DM.SiteID=AD.SiteID
Left Outer Join Production.[dbo].IDViewRecruiters Rec on Acct.RecruiterID=Rec.CodeID
Inner Join Production.[dbo].rpt_CenterDetail CD on DM.CenterID=CD.CenterID
Inner Join Production.[dbo].IDViewCollectionOp CO on CD.CenterID=CO.CodeID
Inner Join Production.[dbo].IDViewRegion Reg on CD.Region=Reg.CodeID
Inner Join Production.[dbo].IDViewOrgCenter Org on CD.OrgCenter=Org.CodeID
Inner Join Production.[dbo].IDViewOrgSubCenter Sub on CD.OrgSubCenter=Sub.CodeID
Inner Join Production.[dbo].rpt_DriveStatusDef DrStat on DM.StatusID=DrStat.StatusID
Inner Join Production.[dbo].DriveProjectionandCollectedTotals DPaCT on DM.DriveID=DPaCT.DriveID
Inner Join #Region As Region On Reg.CodeID = Region.Item
Inner Join #OrgCenter As OrgCenter on Org.CodeID = OrgCenter.Item
Inner Join #SubCenter As SubCenter on Sub.CodeID = SubCenter.Item
Inner Join #CollectionOp as CollectionOp on CO.CodeID = CollectionOp.Item
Left Outer Join #Recruiter as Recruiter on Rec.CodeID = Recruiter.Item
Inner Join #DriveStatus as DriveStatus on DrStat.StatusID = DriveStatus.Item

Where

DM.StatusID <>5
And DM.FromDateTime Between @startDate AND @endDate

【问题讨论】:

  • 您是否先尝试在静态版本中编写此代码,然后再深入研究动态 SQL?这将允许您获得正确的逻辑,然后对其进行转换。
  • 是的,静态版本有效。我的过程是正确的,我现在正尝试将其转换为动态 SQL 以将激励分成单独的列。
  • 您可以编辑以显示您的静态版本吗?然后我们可以将其与您的动态版本进行比较以查看任何问题。
  • 如果仅 ssrs 报告需要动态列,那么您可以尝试使用矩阵。为此,每个激励都应该以行值的形式出现,然后您必须在 SSRS 中按列分组。

标签: sql-server-2008 tsql pivot dynamic-sql


【解决方案1】:

我将表格重新创建为矩阵,并在 Drive ID 字段上创建了一个行分组。然后我在 Incentive 字段上创建了一个列组并将值设置为: =IIF(IsNothing(Fields!Incentive.Value),True,False)

【讨论】:

    猜你喜欢
    • 2014-09-27
    • 2022-01-17
    • 2012-06-13
    • 1970-01-01
    • 1970-01-01
    • 2013-08-10
    • 1970-01-01
    • 2015-03-07
    • 1970-01-01
    相关资源
    最近更新 更多