使用动态列名联接SQL Server

时间:2019-03-29 00:23:25

标签: sql sql-server

我有一个表,可以输出任意数量的不同列(从'Level1'到'Level'N)。

我需要针对CTE对这些动态列中的每一个执行左连接

我编写了以下脚本,但始终收到此错误:

  

信息102,级别15,状态1,第15行,'10'附近的语法不正确。

要进行故障排除,我尝试删除CTE中的每个变量都没有运气。

任何帮助将不胜感激!

DECLARE @rel varchar(4) = CAST('X112' AS varchar(4))
DECLARE @todaysdate date = CONVERT(date,GETDATE())

--create cte

DECLARE @sqltext varchar(MAX) =



' WITH CTE AS
(
SELECT
                 ID 
            ,STARTDATE 
            ,ENDDATE 
            ,NEWID             

FROM Tbl

WHERE TYPE = ''' + @rel + '''
AND ENDDATE >= ' + CAST(@todaysdate AS varchar(30)) +' AND STARTDATE <= ' + CAST(@todaysdate AS varchar(30)) +'
)

SELECT ID, NEWID, Level';

--find max lvl, convert to str

DECLARE @counter int = (SELECT MAX(lvl) FROM tbl2)
DECLARE @counterstring varchar(3)

SET @counterstring = CAST(@counter AS varchar(3))

WHILE @counter != 0 

BEGIN

        SET @sqltext = @sqltext + @counterstring + ' INTO tbl3 '

                             + ' FROM tbl2 a '
                             + ' LEFT JOIN CTE c ON a.Level' + @counterstring + ' = c.NEWID'

        SET @counter = @counter - 1


END

EXEC(@sqltext)

--edited version
DECLARE @rel varchar(4) = CAST('X112' AS varchar(4))
DECLARE @todaysdate date = CONVERT(date,GETDATE())

DECLARE @sqltext varchar(MAX) =

' WITH CTE AS
(
SELECT
                 ID
            ,STARTDATE 
            ,ENDDATE AS mgmt_ENDDA
            ,NEWID

FROM tbl 

WHERE SUBTY = ''' + @rel + '''
AND ENDDATE >= ' + CAST(@todaysdate AS varchar(30)) +' AND STARTDATE <= ' + CAST(@todaysdate AS varchar(30)) +'
)

INSERT INTO tbl3

SELECT ID, NEWID, Level';

DECLARE @counter int = (SELECT MAX(lvl) FROM tbl2)
DECLARE @counterstring varchar(3)


WHILE @counter != 0 

BEGIN

        SET @counterstring = CAST(@counter AS varchar(3))

        SET @sqltext = @sqltext + @counterstring 
                                + ' FROM tbl2 a '
                                + ' LEFT JOIN CTE c ON a.Level' + @counterstring + ' = c.NEWID'
        SET @counter = @counter - 1


END

EXEC(@sqltext)


2 个答案:

答案 0 :(得分:0)

由于select * into查询每次都会创建一个新表,因此我假设您要尝试为'n'个级别创建'n'个表,其结果是通过与第n列联接而获得的。我有2条建议给您

  1. 将选择查询带入while循环并附加';'在循环末尾以拆分选择查询。
  2. 代替INTO tbl3使用INTO tbl + @counterstring作为选择*进入将创建新表

希望这对您有帮助

答案 1 :(得分:0)

您可以这样更改它,然后再试一次吗?

--edited version
DECLARE @rel varchar(4) = CAST('A012' AS varchar(4))
DECLARE @todaysdate date = CONVERT(date,GETDATE())

DECLARE @sqltext varchar(MAX) =

' WITH CTE AS
(
SELECT
                 ID
            ,STARTDATE 
            ,ENDDATE AS mgmt_ENDDA
            ,NEWID

FROM tbl 

WHERE SUBTY = ''' + @rel + '''
AND ENDDATE >= ' + CAST(@todaysdate AS varchar(30)) +' AND STARTDATE <= ' + CAST(@todaysdate AS varchar(30)) +'
)

INSERT INTO tbl3';

DECLARE @counter int = (SELECT MAX(lvl) FROM tbl2)
DECLARE @counterstring varchar(3)


WHILE @counter != 0 

BEGIN

        SET @counterstring = CAST(@counter AS varchar(3))

        SET @sqltext = @sqltext + CHAR(10) +'SELECT ID, NEWID, Level'+@counterstring

        SET @sqltext = @sqltext + ' FROM tbl2 a '
                                + ' LEFT JOIN CTE c ON a.Level' + @counterstring + ' = c.NEWID'

        SET @counter = @counter - 1

        IF @counter <> 0
            SET @sqltext = @sqltext + CHAR(10) + ' UNION '


END

EXEC(@sqltext)

如果您不想摆脱重复的数据,可以尝试使用“ UNION ALL”而不是“ UNION”。希望这会有所帮助