在SQL Server中正确使用PIVOT语句

时间:2014-10-22 11:48:06

标签: sql-server pivot

我有一个审计表,部分数据如下:

Id  ColumnName      Value   RowId
---------------------------------
1   EditCheckId     100     1
2   FieldData_Id    10      1
3   EditType        1       1
4   Outcome         True    1
5   EditCheckId     200     2
6   FieldData_Id    20      2
7   EditType        2       2
8   Outcome         False   2
9   EditCheckId     300     3
10  FieldData_Id    30      3
11  EditType        3       3
12  Outcome         True    3

我想通过RowId

构建这样的表格灌浆数据
EditCheck_Id    FieldData_Id    EditType    Outcome
---------------------------------------------------
100             10              1           True
200             20              2           False               
300             30              3           True

我已尝试过查询:

select [EditCHeck_Id], [FieldData_Id], [EditType], [Outcome]
from
(
    select [ColumnName], [Value]
    from Audit a
) as [SourceTable]
pivot
(
    max([Value])
    for [ColumnName] in ([EditCHeck_Id], [FieldData_Id], [EditType], [Outcome])
) as [PivotTable];

http://sqlfiddle.com/#!6/7af71/3

使用PIVOT语句,但答案中只有一行。我的问题在哪里?

2 个答案:

答案 0 :(得分:0)

您需要GROUP BY的某些值才能使每个行都不同。通常,您可以使用row_number()之类的窗口函数在当前columnname上生成唯一的序列号。您可以将查询更改为以下内容:

select 
  [EditCheckId], 
  [FieldData_Id], 
  [EditType], 
  [Outcome]
from
(
  select [ColumnName], [Value],
    rn = row_number() over(partition by ColumnName order by id)
  from Audit a
) as [SourceTable]
pivot
(
    max([Value])
    for [ColumnName] in ([EditCheckId], [FieldData_Id], [EditType], [Outcome])
) as [PivotTable];

SQL Fiddle with Demo

您还可以使用带有CASE表达式的聚合函数来获得最终结果:

select 
  max(case when ColumnName = 'EditCheckId' then value end) [EditCheckId], 
  max(case when ColumnName = 'FieldData_Id' then value end) [FieldData_Id], 
  max(case when ColumnName = 'EditType' then value end) [EditType], 
  max(case when ColumnName = 'Outcome' then value end) [Outcome]
from
(
  select [ColumnName], [Value],
    rn = row_number() over(partition by ColumnName order by id)
  from Audit a
) d
group by rn;

请参阅SQL Fiddle with Demo两者都给出结果:

| EDITCHECKID | FIELDDATA_ID | EDITTYPE | OUTCOME |
|-------------|--------------|----------|---------|
|         100 |           10 |        1 |    True |
|         200 |           20 |        2 |   False |
|         300 |           30 |        3 |    True |

答案 1 :(得分:0)

您需要区分输出行,例如您的RowId

pivot为你做分组是这样的:

select [RowID], [EditCheckId], [FieldData_Id], [EditType], [Outcome]
from
(
    select [ColumnName], [Value], [RowId]
    from Audit a
) as [SourceTable]
pivot
(
    max([Value])
    for [ColumnName] in ([EditCheckId], [FieldData_Id], [EditType], [Outcome])
) as [PivotTable];

edited Fiddle demo