我想从一个表中选择特定的列,假设表A。表B有我想要选择的列的名称。如何编写MSSQL查询,该查询将使用表B中的不同值作为我要从表A查询的列名?
发布于 2015-06-01 17:28:06
你就不能像这样使用聚结函数吗?
DECLARE @columnList VARCHAR(MAX), @sql VARCHAR(MAX)
SELECT @columnList = COALESCE(@columnList+',' ,'') + columnName
FROM TableB
SET @sql = 'SELECT ' + @columnList + ' FROM TableA'
EXEC(@sql)发布于 2015-06-01 16:42:17
最简单的方法是使用动态SQL。您将使用表B值构建查询字符串,然后执行它。下面是一个示例,如果您想提供更多的细节,即表结构和示例数据,我可以尝试提供更详细的帮助。
使用固定列的示例1:
DECLARE @col1 varchar(25)
DECLARE @col2 varchar(25)
DECLARE @col3 varchar(25)
DECLARE @sqlcmd varchar(250)
SET @col1 = columnname from [dbo].[TableB] where id = 1
SET @col2 = columnname from [dbo].[TableB] where id = 2
SET @col3 = columnname from [dbo].[TableB] where id = 3
SET @sql = 'SELECT ' + @col1 + ',' + @col2 + ',' + @col3 + ' FROM dbo.TableA;'
EXECUTE (@sqlcmd);示例2包含动态列(包括示例表和数据):
CREATE TABLE tempdb.dbo.columnlist (columnname varchar(50))
INSERT INTO tempdb.dbo.columnlist (columnname) VALUES
('name'),('age'),('zipcode')
CREATE TABLE tempdb.dbo.TableA (name varchar(25), age varchar(3), zipcode varchar(15))
INSERT INTO tempdb.dbo.TableA (name, age, zipcode) VALUES
('john', '10', '90210'),('jake', '103', '90210'),('jane', '85', '90210')
DECLARE @sqlcmd varchar(250)
DECLARE @columnname varchar(50)
DECLARE cr_columnlist CURSOR FOR
SELECT DISTINCT columnname FROM tempdb.dbo.columnlist
SET @sqlcmd = 'SELECT '
OPEN cr_columnlist
FETCH NEXT FROM cr_columnlist INTO @columnname
WHILE @@FETCH_STATUS = 0
BEGIN
SET @sqlcmd = @sqlcmd + @columnname + ', '
FETCH NEXT FROM cr_columnlist INTO @columnname
END
CLOSE cr_columnlist
DEALLOCATE cr_columnlist
SET @sqlcmd = LEFT(@sqlcmd, LEN(@sqlcmd) - 1) -- Remove trailing comma and space
SET @sqlcmd = @sqlcmd + ' FROM tempdb.dbo.TableA;' -- Finish statement with FROM table
EXECUTE (@sqlcmd)发布于 2015-06-01 18:48:59
USE tempdb;
GO
CREATE TABLE dbo.TableA(col1 INT, col2 INT, col3 INT);
CREATE TABLE dbo.TableB([column] NVARCHAR(128));
INSERT dbo.TableB([column]) VALUES(N'col1'),(N'col3'),
(N'fake column'),(N'x;DROP TABLE dbo.BobbyTables;--');
DECLARE @sql NVARCHAR(MAX);
SELECT @sql = N'SELECT ' + STUFF((SELECT N',' + QUOTENAME([column])
FROM dbo.TableB
WHERE [column] IN
(
SELECT name FROM sys.columns
WHERE [object_id] = OBJECT_ID(N'dbo.tableA')
)
FOR XML PATH, TYPE).value(N'.[1]','nvarchar(max)'),1,1,N'')
+ N' FROM dbo.TableA;';
PRINT @sql;
EXEC sys.sp_executesql @sql;结果:
SELECT [col1],[col3] FROM dbo.TableA;
-- note that fake column wasn't included,
-- nor was a DROP TABLE attempted.讨论潜在问题(包括其他答复中建议的问题)的一些背景读物:
https://dba.stackexchange.com/questions/102968
复制相似问题