首先,我是SQL新手。以下是示例(对于table1
和table2
,我创建了一个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中实现上述所需的输出?
答案 0 :(得分:5)
您可以使用PIVOT获取结果,但您还需要取消忽略ModifiedDate
和Operator
列,以便在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列PName
,ModifiedDate
和Operator
转换为单个列。这是必要的,因此您可以轻松获取每个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 |