在转动数据方面需要帮助吗?

时间:2014-04-01 12:31:30

标签: sql sql-server-2008 pivot

首先,我是SQL新手。以下是示例(对于table1table2,我创建了一个SNO作为主键,它也是标识列)

表1

PID  PNAME    PartID
---  -----    ------
0    Length   1
1    Breadth  1
2    Height   1
0    Area     2
1    Volume   2

表2

SampleID  PID  Pvalue  PartID  ModifiedDate  Operator
--------  ---  ------  ------  ------------  --------
0         0    10      1       10-Mar-14     Test
0         1    10      1       10-Mar-14     Test
0         2    Fail    1       10-Mar-14     Test
1         0    20      1       12-Mar-14     Test
1         1    Fail    1       12-Mar-14     Test
1         2    Fail    1       12-Mar-14     Test
0         0    10      2       13-Mar-14     Test1
0         1    10      2       13-Mar-14     Test1

根据PartID,我必须得到以下结果

PARTID:1

PNAME         0          1
------------  ---------  ---------
Length        10         20
Breadth       10         Fail
Height        Fail       Fail
ModifiedDate  10-Mar-14  12-Mar-14
Operator      Test       Test

PARTID:2

PNAME         0
------------  ---------
Area          10
Volume        10
ModifiedDate  13-Mar-14
Operator      Test1

如何在SQL Server 2008中实现上述所需的输出?

1 个答案:

答案 0 :(得分:5)

您可以使用PIVOT获取结果,但您还需要取消忽略ModifiedDateOperator列,以便在PName的单个列中显示它们。您的最终结果将需要一个动态解决方案,但首先编写此静态然后转换为动态sql会更容易。

基本语法为:

select pname, [0], [1]
from
(
  select t2.sampleid, pname = c.col, c.value
  from table1 t1
  inner join table2 t2
    on t1.partid = t2.partid
    and t1.pid = t2.pid
  cross apply
  (
    select Pname, pvalue union all
    select 'ModifiedDate', convert(varchar(10), ModifiedDate, 120) union all
    select 'Operator', Operator
  ) c (col, value)
  where t1.partid = 1
) d
pivot
(
  max(value)
  for sampleid in ([0], [1])
) p;

SQL Fiddle with Demo。您会看到我使用CROSS APPLY将3列PNameModifiedDateOperator转换为单个列。这是必要的,因此您可以轻松获取每个SampleId的值。上面的版本是静态版本,这意味着您要对最终列的值进行硬编码,但如果您希望根据PartId进行此调整,则需要使用动态SQL:

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX),
    @partid int,
    @paramdef nvarchar(max)

set @partid = 1
set @paramdef = '@partid int'

select @cols = STUFF((SELECT ',' + QUOTENAME(sampleid) 
                    from Table2
                    where partid = @partid
                    group by sampleid
                    order by sampleid
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT pname,' + @cols + ' 
            from 
            (
              select t2.sampleid, pname = c.col, c.value
              from table1 t1
              inner join table2 t2
                on t1.partid = t2.partid
                and t1.pid = t2.pid
              cross apply
              (
                select Pname, pvalue union all
                select ''ModifiedDate'', convert(varchar(10), ModifiedDate, 120) union all
                select ''Operator'', Operator
              ) c (col, value)
              where t1.partid = @partid
            ) x
            pivot 
            (
                max(value)
                for sampleid in (' + @cols + ')
            ) p '

exec sp_executesql @query, @paramdef, @partid = @partid;

SQL Fiddle with Demo。两者都给出了结果:

|        PNAME |          0 |          1 |
|--------------|------------|------------|
|      Breadth |         10 |       Fail |
|       Height |       Fail |       Fail |
|       Length |         10 |         20 |
| ModifiedDate | 2014-03-10 | 2014-03-12 |
|     Operator |       Test |       Test |