我正在尝试基于行和列值映射创建结果。这是一个示例
第一个表(#column_table)具有colunm_id和column_name。
第二个表#column_value具有第一个表中各行的值。
我想创建一个如下所示的数据集:
我该如何实现?
以下是用于数据设置的临时表。
create table #column_table (column_id int, column_name varchar(50) )
insert into #column_table
values
(1, 'FirstName'),
(2, 'LastName'),
(3, 'Address'),
(4, 'Phone')
create table #column_value(FirstName varchar(50), LastName varchar(50), Phone varchar(50),)
insert into #column_value
values
('John','Smith','1234567')
select * from #column_table
select * from #column_value
答案 0 :(得分:3)
UNPIVOT 会更有效,但是如果您需要一种更动态的方法而又不实际使用动态SQL
示例
Select D.Column_ID
,Column_Value = C.Value
From #column_value A
Cross Apply (values (convert(xml,(Select A.* For XML Raw)))) B(XMLData)
Cross Apply (
Select Item = xAttr.value('local-name(.)', 'varchar(100)')
,Value = xAttr.value('.','varchar(max)')
From XMLData.nodes('//@*') xNode(xAttr)
) C
Join #column_table D on C.Item=D.Column_Name
返回
Column_ID Column_Value
1 John
2 Smith
4 1234567
答案 1 :(得分:3)
您可以使用性能更强的 UnPivot 实现此目的,但是正如@JohnCappelleti所述,您需要实现动态SQL 逻辑:
侧面说明:我使用like '#column_value%'
而不是= '#column_value'
,因为该示例正在处理临时表。另外,您应该用相应的表名称替换#column_value
和#column_table
。另外,我使用tempdb.information_schema
是因为临时表存储在tempdb
数据库中。
--Create Tables and insert values
create table #column_table (column_id int, column_name varchar(50) )
insert into #column_table
values
(1, 'FirstName'),
(2, 'LastName'),
(3, 'Address'),
(4, 'Phone')
create table #column_value(FirstName varchar(50), LastName varchar(50), Phone varchar(50),)
insert into #column_value
values
('John','Smith','1234567')
select * from #column_table
select * from #column_value
--Get columns found in both tables
SELECT t2.column_id,t2.column_name
INTO #tblTemp
from tempdb.information_schema.columns t1
inner join #column_table t2 on t1.COLUMN_NAME = t2.column_name
where t1.table_name like '#column_value%'
--Building Dynamic Query
DECLARE @strQuery VARCHAR(4000) = 'SELECT * FROM (SELECT '
DECLARE @strUnPivot as varchar(max) = ' UNPIVOT ([Value] for [Column_ID] IN ('
SELECT @strUnPivot = ISNULL(@strUnPivot,'') + '[' + CAST(column_id as varchar(10)) + '] ,' From #tblTemp
SELECT @strQuery = @strQuery + '[' + column_name + '] AS "' + CAST(column_id as varchar(10)) + '",' From #tblTemp
SELECT @strQuery = SUBSTRING(@strQuery,1,LEN(@strQuery) - 1) + ' FROM #column_value) AS p ' + SUBSTRING(@strUnPivot,1,LEN(@strUnPivot) - 1) + ')) AS unpvt '
--Execute Query
EXEC(@strQuery)
结果
参考
答案 2 :(得分:1)
使用CASE
和交叉连接:
select
ct.column_id,
case ct.column_id
when 1 then cv.FirstName
when 2 then cv.LastName
when 4 then cv.Phone
end column_value
from #column_table ct cross join #column_value cv
where ct.column_id <> 3
请参见demo