Pivot或Cross Tab

时间:2013-11-28 18:12:15

标签: sql join sql-server-2008-r2 database-table

我有两个表需要链接并以人性化的方式呈现数据。你能否请专家指出我正确的方向,我有点卡在这里。

表1和表2都通过ftp接收并加载到SQL 2008 R2中的SQL表。这两个表由nidcid链接在一起。

道歉我无法复制粘贴表,请考虑“ - ”是列分隔符

表1

ID  nid  cid  pid  form_key-name
 1    4    1   33  Import_Gen_Title-Title
 2    4    2   33  Import_Gen_Firstname-Firstname
 3    4    3   33  Import_Gen_Surname-Surname
 4    4    4   33  Import_Gen_AddressLine1-AddressLine1
 5    4    5   33  Import_Gen_AddressLine2-AddressLine2
 6    4    6   33  Import_Gen_City-Town/City
 7    4    7   33  Import_Gen_Zip-Post code

表2

ID  nid sid cid data
 1    4  14   1  Mr
 2    4  14   2  John
 3    4  14   3  Smith
 4    4  14   4  A Company
 5    4  14   5  Nice Street
 6    4  14   6  London
 7    4  14   7  SE11 0TS

现在如何才能得到如下所示的结果表?

NiD  SID Title  Firstname Surname  AddressLine1  AddressLine2  Town/City-Post code
  4   14    Mr       John   Smith  A Company     Nice Street   London-SE11 0TS

2 个答案:

答案 0 :(得分:0)

使用Pivot:Fiddle demo

SELECT sid, nid,
       [Import_Gen_Title-Title] as Title,
       [Import_Gen_Firstname-Firstname] as Name,
       [Import_Gen_Surname-Surname] as SurName,
       [Import_Gen_AddressLine1-AddressLine1] as Address1,
       [Import_Gen_AddressLine2-AddressLine2] as Address2,
       [Import_Gen_City-Town/City] as Town,
       [Import_Gen_Zip-Post code] as PostCode
FROM
(
  SELECT t2.sid, t2.nid, t2.dat, t1.form_key
  FROM tab1 t1 INNER JOIN tab2 t2 ON t1.nid = t2.nid AND t1.cid = t2.cid
) x
PIVOT
(  
  min(x.dat)
  for x.form_key in ([Import_Gen_Title-Title],
                     [Import_Gen_Firstname-Firstname],
                     [Import_Gen_Surname-Surname],
                     [Import_Gen_AddressLine1-AddressLine1],
                     [Import_Gen_AddressLine2-AddressLine2],
                     [Import_Gen_City-Town/City],
                     [Import_Gen_Zip-Post code]
                    )
) pvt

编辑(添加通用版本):Fiddle demo

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX);

SET @cols = STUFF((SELECT ',[' + t.form_key + ']'
            FROM tab1 t
            group by t.form_key, cid
            order by t.cid
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)'),1,1,'');

SET @query = 'SELECT * FROM
(
  SELECT t2.sid, t2.nid, t2.dat, t1.form_key
  FROM tab1 t1 INNER JOIN tab2 t2 ON t1.nid = t2.nid AND t1.cid = t2.cid
) x
PIVOT
(
  min(x.dat)
  FOR x.form_key IN (' + @cols + ')
) pvt;';

execute(@query);

答案 1 :(得分:0)

在此处查看我对此问题的答案:Pivot in sql server

我创建了一个使用salvoo显示的PIVOT语句的存储过程 - 但它更通用,您不必事先知道所有列。

看看。

以下是使用您的数据的示例 - 请注意,数据透视的默认输出具有您不想要的字母顺序列 - 所以我使用该选项将数据输出到临时表,然后直接从临时表以按照您想要的顺序放置列。

drop table Fields
go
drop table Data
go
create table Fields
   (
   ID                   Integer,
   nid                  Integer,
   cid                  Integer,
   pid                  Integer,
    form_key_name       varchar(50)
   );
go
create table Data
   (
   ID                   Integer,
   nid                  Integer,
   sid                  Integer,
   cid                  Integer,
   data                 varchar(50)
   );
go
insert into Fields values (1,4,1,33,'Import_Gen_Title-Title')
go
insert into Fields values (2,4,2,33,'Import_Gen_Firstname-Firstname')
go
insert into Fields values (3,4,3,33,'Import_Gen_Surname-Surname')
go
insert into Fields values (4,4,4,33,'Import_Gen_AddressLine1-AddressLine1')
go
insert into Fields values (5,4,5,33,'Import_Gen_AddressLine2-AddressLine2')
go
insert into Fields values (6,4,6,33,'Import_Gen_City-Town/City')
go
insert into Fields values (7,4,7,33,'Import_Gen_Zip-Post code')
go
insert into Data values (1,4,14,1,'Mr')
go
insert into Data values (2,4,14,2,'John')
go
insert into Data values (3,4,14,3,'Smith')
go
insert into Data values (4,4,14,4,'A Company')
go
insert into Data values (5,4,14,5,'Nice Street')
go
insert into Data values (6,4,14,6,'London')
go
insert into Data values (7,4,14,7,'SE11 0TS')
go
declare @mySQL varchar(MAX);

set @mySQL = '
select
   f.nid,
   d.sid,
   right(f.form_key_name, len(f.form_key_name) - charindex(''-'',f.form_key_name)) form_key_name,
   d.data
from
   Fields f

   JOIN Data d
      on ( d.nid = f.nid
           and d.cid = f.cid )
   ';

exec pivot_query @mySQL, 'nid, sid', 'form_key_name','max(data)', '##tmppivot';

select
   nid,
   sid,
   Title,
   Firstname,
   Surname,
   AddressLine1,
   AddressLine2,
   [Town/City],
   [Post code]
from
   ##tmppivot;
go