SQL Server映射具有不同表列的行

时间:2019-02-14 21:26:41

标签: sql sql-server tsql sql-server-2016

我正在尝试基于行和列值映射创建结果。这是一个示例

第一个表(#column_table)具有colunm_id和column_name。

enter image description here

第二个表#column_value具有第一个表中各行的值。

enter image description here

我想创建一个如下所示的数据集:

enter image description here

我该如何实现?

以下是用于数据设置的临时表。

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

3 个答案:

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

结果

enter image description here

参考

答案 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