2013-04-09 63 views
0

我有产生如下图所示枢轴表创建多个表,名称中包含列名和文本包含他们的价值观,所以需要根据相似的价值观如何从数据透视表

输入生成多个表表

ID Name text  
1 Name,DOB John,02/02/1980 
2 FirstName,SSN,City Ray,987898789,Chicago 
3 Name,DOB Mary,12/21/1990 
4 FirstName,SSN,City Cary,987000789,Dallas 
5 PersonID,Code,Zip,Gender,Maritial 1234,A456,23456,M,single  
6 PersonID,Code,Zip,Gender,Maritial 1235,A457,23233,M,single  
7 PersonID,Code,Zip,Gender,Maritial 1236,A458,67675,M,Married 

所以输出表应该像

输出表1

ID Name DOB 
1 john 02/02/1980 
3 Mary 02/02/1980 

输出表2

ID FirstName SSN City 
2 Ray 987898789 Chicago 
4 Cary 987000789 Dallas 

输出表3

ID PersonID Zip Gender Marital 
5 1234 A456 23456 M Single 
6 1235 A457 23233 M Single 
7 1236 A458 67675 M Married 

能有人请帮我在这一个。可以这样做在Sqlserver或MySQL或SSIS?

+1

只需用手对每个查询类型进行硬编码;没有对此的自动化支持,但它比困难更繁琐。 – 2013-04-09 22:18:35

回答

2

我的建议是首先规范你的input表。在SQL Server中,您可以使用递归CTE将逗号分隔列表中的数据拆分为多行。

的CTE将类似于以下内容:

;with cte (id, col, Name_list, value, text_list) as 
(
    select id, 
    cast(left(Name, charindex(',',Name+',')-1) as varchar(50)) col, 
     stuff(Name, 1, charindex(',',Name+','), '') Name_list, 
    cast(left(text, charindex(',',text+',')-1) as varchar(50)) value, 
     stuff(text, 1, charindex(',',text+','), '') text_list 
    from input 
    union all 
    select id, 
    cast(left(Name_list, charindex(',',Name_list+',')-1) as varchar(50)) col, 
    stuff(Name_list, 1, charindex(',',Name_list+','), '') Name_list, 
    cast(left(text_list, charindex(',',text_list+',')-1) as varchar(50)) value, 
     stuff(text_list, 1, charindex(',',text_list+','), '') text_list 
    from cte 
    where Name_list > '' 
    or text_list > '' 
) 
select id, col, value 
from cte; 

SQL Fiddle with Demo。这将让你在格式的数据:

| ID |  COL |  VALUE | 
------------------------------- 
| 1 |  Name |  John | 
| 2 | FirstName |  Ray | 
| 3 |  Name |  Mary | 
| 4 | FirstName |  Cary | 
| 5 | PersonID |  1234 | 

一旦数据在格式,然后你可以枢根据您在每个表所需的列中的数据。

例如,如果你想为Table1数据,您将使用:

;with cte (id, col, Name_list, value, text_list) as 
(
    select id, 
    cast(left(Name, charindex(',',Name+',')-1) as varchar(50)) col, 
     stuff(Name, 1, charindex(',',Name+','), '') Name_list, 
    cast(left(text, charindex(',',text+',')-1) as varchar(50)) value, 
     stuff(text, 1, charindex(',',text+','), '') text_list 
    from input 
    union all 
    select id, 
    cast(left(Name_list, charindex(',',Name_list+',')-1) as varchar(50)) col, 
    stuff(Name_list, 1, charindex(',',Name_list+','), '') Name_list, 
    cast(left(text_list, charindex(',',text_list+',')-1) as varchar(50)) value, 
     stuff(text_list, 1, charindex(',',text_list+','), '') text_list 
    from cte 
    where Name_list > '' 
    or text_list > '' 
) 
select * 
-- into table1 
from 
(
    select id, col, value 
    from cte 
    where col in ('Name', 'DOB') 
) d 
pivot 
(
    max(value) 
    for col in (Name, DOB) 
) piv; 

SQL Fiddle with Demo

你会再与下一个表中的值替换每个查询的列名。