首页 > 解决方案 > 如何根据 id 列表在 SQL 中动态创建列

问题描述

我正在用 SQL 开发一个存储过程,它从后端接收 Ids (INT) 列表。我需要根据这些动态创建列,并为每个 ID 的列命名。以下是如何使用固定数量的已知 ID 执行此操作的示例

SELECT DISTINCT
    SE.SE_optionCode AS OptionCode,
    LTRIM(RTRIM(DO.DO_Description)) AS Description,
    LTRIM(RTRIM(CASE WHEN DG.DG_Description IS NULL THEN '' ELSE DG.DG_Description END)) AS GenericDescription,
    LTRIM(RTRIM(CASE WHEN DG.DG_GenericCode IS NULL THEN 0 ELSE DG.DG_GenericCode END))  as GenericCode,
    DCS.DC_CatCode AS Category,
    LTRIM(RTRIM(DCS.DC_Description)) AS Category,
    DCG.DC_CatCode AS GenericCategory,
    LTRIM(RTRIM(DCG.DC_Description)) AS GenericCategory,
    (SELECT DISTINCT 1 FROM NVDStandardEquipment WHERE SE_id = 93762 AND SE_optionCode = SE.SE_optionCode AND SE.SE_effectiveTo IS NULL) as Vehicle1,
    (SELECT DISTINCT 1 FROM NVDStandardEquipment WHERE SE_id = 93786 AND SE_optionCode = SE.SE_optionCode AND SE.SE_effectiveTo IS NULL) as Vehicle2,
    (SELECT DISTINCT 1 FROM NVDStandardEquipment WHERE SE_id = 93787 AND SE_optionCode = SE.SE_optionCode AND SE.SE_effectiveTo IS NULL) as Vehicle3,
    (SELECT DISTINCT 1 FROM NVDStandardEquipment WHERE SE_id = 93801 AND SE_optionCode = SE.SE_optionCode AND SE.SE_effectiveTo IS NULL) as Vehicle4        
FROM NVDStandardEquipment SE (NOLOCK)
INNER JOIN NVDDictionaryOption DO (NOLOCK) ON DO.DO_OptionCode = SE.SE_optionCode
INNER JOIN NVDDictionaryOptionGenericCatLink DOGCL (NOLOCK) ON DOGCL.OGCL_OptionCatCode = DO.DO_CatCode
LEFT JOIN NVDDictionaryOptionGenericLink DOGL ON DOGL.ogl_optioncode = SE.SE_optionCode
LEFT JOIN NVDDictionaryGeneric DG ON DG.DG_GenericCode = DOGL.OGL_genericCode
INNER JOIN NVDDictionaryCategory DCS (NOLOCK) ON DCS.DC_CatCode = DO.DO_CatCode
INNER JOIN NVDDictionaryCategory DCG (NOLOCK) ON DCG.DC_CatCode = DOGCL.OGCL_GenericCatCode
WHERE SE.SE_id in (93762,93786,93787,93801)

这将返回一个结果集,如附加图像中所示。

结果

在我的存储过程中,我声明了一个临时表,其中存储了从后端接收到的所有 Id,不知何故我必须遍历这些(不确定这是否是最好的方法),我不知道是否可以生成根据示例生成基于 ID 列表的相同输出,是否有人做过类似的事情或对我如何实现这一点有一些想法?

提前致谢!

标签: sqlsql-servertsqlstored-procedures

解决方案


假设您需要更新/维护下表。

CREATE TABLE [dbo].[Test1](
    [MemberID] [varchar](50) NULL,
    [InpatientDays] [varchar](50) NULL,
    [ERVisits] [varchar](50) NULL,
    [OfficeVisits] [varchar](50) NULL,
    [Narcotics] [varchar](50) NULL,
    [DaysSinceLastERVisit] [varchar](50) NULL,
    [Pain] [varchar](50) NULL,
    [TotalVisits] [varchar](50) NULL
) ON [PRIMARY]
GO

您有一个包含以下 ID 列表的文件。

AcuteDrugGapSmall
ClaimLines
MedicalClaims
PoorCare
ProviderCount
StartedOnCombination

创建一个表来保存 ID。

CREATE TABLE [dbo].[Test2](
    [ID] [varchar](50) NULL
) ON [PRIMARY]
GO

插入 ID 后,运行以下命令以生成 TSQL 脚本以添加新列。我假设在这个例子中它们都是 VARCHAR(50) 。您可以根据有关 data_type 和 character_maximum_length 的更多信息调整代码。如果需要,您可以采用类似的方法来删除列。如果您在表 Test2 中有一个标志,指示是添加还是删除该列。

 DECLARE @SQL VARCHAR(MAX)
SELECT @SQL = STRING_AGG('ALTER TABLE [dbo].[Test1] ADD ' + ID  + ' VARCHAR(50)', '   ')
FROM [dbo].[Test3]

EXECUTE (@SQL)

上面的脚本生成并执行以下内容。如果这对您有用,请标记为解决方案。

ALTER TABLE [dbo].[Test1] ADD AcuteDrugGapSmallVARCHAR(50)
ALTER TABLE [dbo].[Test1] ADD ClaimLinesVARCHAR(50)
ALTER TABLE [dbo].[Test1] ADD MedicalClaimsVARCHAR(50)
ALTER TABLE [dbo].[Test1] ADD PoorCareVARCHAR(50)
ALTER TABLE [dbo].[Test1] ADD ProviderCountVARCHAR(50)
ALTER TABLE [dbo].[Test1] ADD StartedOnCombinationVARCHAR(50)

推荐阅读