简体   繁体   English

使用动态列名SQL Server加入

[英]Join using dynamic column names SQL Server

I have a table which can output any number of different columns (from 'Level1' to 'Level'N). 我有一个表可以输出任意数量的不同列(从'Level1'到'Level'N)。

I need to perform a left join on each of these dynamic columns against a CTE 我需要针对CTE在每个动态列上执行左连接

I have written the following script but keep getting this error: 我写了以下脚本,但一直收到此错误:

Msg 102, Level 15, State 1, Line 15 Incorrect syntax near '10'. 消息102,级别15,状态1,行15'10'附近的语法不正确。

To troubleshoot, I have tried removing the each of the variables in the CTE with no luck. 要进行故障排除,我尝试删除CTE中的每个变量,但没有运气。

Any help would be much appreciated! 任何帮助将非常感激!

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)


Since select * into query creates a new table each time, I am assuming that you are trying to create 'n' number of tables for 'n' number of levels, with the result obtained by joining with nth column. 由于select * into查询每次创建一个新表,我假设您正在尝试为'n'个级别创建'n'个表,并通过加入第n列获得结果。 I have 2 suggestions for you 我有2条建议给你

  1. Bring the select query within the while loop and append ';' 在while循环中引入select查询并追加';' at the end of the loop to split select queries. 在循环结束时拆分选择查询。
  2. instead of INTO tbl3 use INTO tbl + @counterstring as select * into will create new table 而不是INTO tbl3使用INTO tbl + @counterstring作为select * into将创建新表

Hope this helps you 希望这对你有所帮助

Can you change it like this and try again? 你可以像这样改变它并再试一次吗?

--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)

You can try 'UNION ALL' instead of 'UNION' if you dont want to get rid of duplicate data. 如果您不想删除重复数据,可以尝试“UNION ALL”而不是“UNION”。 Hope this helps 希望这可以帮助

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM