2012-11-28 66 views
0

这是我的查询行转换成列

select * from dbo.tblHRIS_ChildDetails where intSID=463 

输出:

intCHID intsid nvrchildname nvrgender  dttchildDOB     Occupation 
     3  463  SK   Female  2001-12-11 00:00:00.000 Studying  
     4  463  SM   Male  2007-10-08 00:00:00.000 Student 

我需要这样这样输出的查询是动态的,它可以返回基于intSID

行的n个
chidname1 gender DOB childoccupation1   chidname2 gender DOB childoccupation2 
    SK  female 2001-12-11 00:00:00.000 studying  SM  Male 2007-10-08 00:00:00.000  Student 
+0

这是什么RDBMS? –

+0

Sql server 2005 –

+0

使用关系模型时,你所要求的通常不会完成。你能告诉我们为什么你想要(或想你想要)这样做吗? – jimhark

回答

0

你必须提供不同的列名称,但除此之外,它很简单。但正如其他人所说,这不是通常的做法,看起来像是如果你想用两列打印报告。

select 
    max(case when intCHID=1 then nvrchildname end) as chidname1, 
    max(case when intCHID=1 then gender  end) as gender1, 
    max(case when intCHID=1 then dttchildDOB end) as DOB1, 
    max(case when intCHID=1 then Occupation end) as cildOccupation1, 
    max(case when intCHID=2 then nvrchildname end) as chidname2, 
    max(case when intCHID=2 then gender  end) as gender2, 
    max(case when intCHID=2 then dttchildDOB end) as DOB2, 
    max(case when intCHID=2 then Occupation end) as cildOccupation2 
from 
    dbo.tblHRIS_ChildDetails 
where 
    intSID=463 
+0

我不能通过这intCHID = 1这是自动生成的列 –

2

对于这种类型的数据,您需要同时实现UNPIVOT,然后PIVOT的SQL Server的功能。 UNPIVOT从多列中提取数据并将其放在两列中,然后应用PIVOT将数据转换回列。

如果你知道所有你想要转换的值,那么你可以硬编码,与此类似:

select * 
from 
(
    select value, col+'_'+cast(rn as varchar(10)) col 
    from 
    (
    select nvrchildname, 
     nvrgender, 
     convert(varchar(10), dttchildDOB, 120) dttchildDOB, 
     occupation, 
     row_number() over(partition by intsid order by intCHID) rn 
    from tblHRIS_ChildDetails 
    where intsid = 463 
) src 
    unpivot 
    (
    value 
    for col in (nvrchildname, nvrgender, dttchildDOB, occupation) 
) unpiv 
) src1 
pivot 
(
    max(value) 
    for col in ([nvrchildname_1], [nvrgender_1], 
       [dttchildDOB_1], [occupation_1], 
       [nvrchildname_2], [nvrgender_2], 
       [dttchildDOB_2], [occupation_2]) 
) piv 

SQL Fiddle with Demo

现在,如果你有一个未知号码值进行改造,那么你可以使用动态SQL这样的:

DECLARE @colsUnpivot AS NVARCHAR(MAX), 
    @query AS NVARCHAR(MAX), 
    @colsPivot as NVARCHAR(MAX) 

select @colsUnpivot = stuff((select ','+quotename(C.name) 
     from sys.columns as C 
     where C.object_id = object_id('tblHRIS_ChildDetails') and 
       C.name not in ('intCHID', 'intsid') 
     for xml path('')), 1, 1, '') 

select @colsPivot = STUFF((SELECT ',' 
         + quotename(c.name 
         +'_'+ cast(t.rn as varchar(10))) 
        from 
        (
         select row_number() over(partition by intsid order by intCHID) rn 
         from tblHRIS_ChildDetails 
        ) t 
        cross apply sys.columns as C 
        where C.object_id = object_id('tblHRIS_ChildDetails') and 
         C.name not in ('intCHID', 'intsid') 
        group by c.name, t.rn 
        order by t.rn 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

set @query 
    = 'select * 
     from 
     (
     select col+''_''+cast(rn as varchar(10)) col, value 
     from 
     (
      select nvrchildname, 
      nvrgender, 
      convert(varchar(10), dttchildDOB, 120) dttchildDOB, 
      occupation, 
      row_number() over(partition by intsid order by intCHID) rn 
      from tblHRIS_ChildDetails 
      where intsid = 463 
     ) x 
     unpivot 
     (
      value 
      for col in ('+ @colsunpivot +') 
     ) u 
    ) x1 
     pivot 
     (
     max(value) 
     for col in ('+ @colspivot +') 
    ) p' 

exec(@query) 

SQL Fiddle with Demo

这两个查询的结果是:

| NVRCHILDNAME_1 | NVRGENDER_1 | DTTCHILDDOB_1 | OCCUPATION_1 | NVRCHILDNAME_2 | NVRGENDER_2 | DTTCHILDDOB_2 | OCCUPATION_2 | 
----------------------------------------------------------------------------------------------------------------------------- 
|    SK |  Female | 2001-12-11 |  Studying |    SM |  Male | 2007-10-08 |  Student | 
+0

我有一些疑问,你的解决方案是一流的,但我有性别,职业,childname作为nvarchar,所以如果运行查询我得到一些错误有这个小提琴的外观PLZ http://sqlfiddle.com/#!3/164b7/1 –

+0

你可以检查这一点,并告诉 –

+0

你看到了小提琴:) –