开发者

SQL Pivot Table

I have a SQL view with following data:

ID   ClassName    Description   Flags
1    Class1         Desc1        F1
2    Class1         Desc1        F2
3    Class1         Desc1        F3
4    Class1         Desc1        F4
5    Class2         Desc2        F2
6    Class2         Desc2        F6
7    Class3         Desc3        F1
8    Class4         Desc4        F8

I want result something like this:

ClassName    Description    F1   F2  F3  F4  F6 开发者_StackOverflow  F8
Class1         Desc1         T    T  T    T   F   F
Class2         Desc2         F    T  F    F   T   F
Class3         Desc3         T    F  F    F   F   F
Class4         Desc4         F    F  F    F   F   T

I have tried to look up for Pivot examples but all of them are either for SUM or other aggregate functions. Not sure if any of that will work as I'm not doing either.


Henry Fao is on the right track - but you have to "flatten" the rows with a group by.

select ClassName as ClassName, Description as Description 
   , coalesce(max(F1), 'F') as F1
   , coalesce(max(F2), 'F') as F2
   , etc
 from (
        select classname, description
           , case when flags = 'F1' then 'T' else null end as F1
           , case when flags = 'F2' then 'T' else null end as F2
           etc.
        from tbl
       ) as t
  group by ClassName, Description

There should only be one 'T' in the F1 column of each group. The other rows will have a null in the T1 column. The max() function ignores nulls and will return the 'T' - if there is one.


I believe MS SQL Server supports pivots tables, but I'm not sure exactly how to do them. When I have to pivot data in MySQL, I use Sum and Case. However, that only works when you know what your column names are going to be in advance. Here's how I might do it:

Select
X.ClassName,
X.Description,
Case When X.F1 = 1 Then 'T' Else 'F' End As `F1`,
Case When X.F2 = 1 Then 'T' Else 'F' End As `F2`
/* etc. for the rest of your Flags*/
FROM (
    Select
    ClassName,
    Description,
    Sum(Case When Flags = 'F1' Then 1 Else 0 End) As `F1`,
    Sum(Case When Flags = 'F2' Then 1 Else 0 End) As `F2`
    /* etc. for the rest of your Flags*/
    From 
    ClassTable
    Group By
    ClassTable.ClassName
    ) X

In the above code, the subquery will produce output like what you wanted, except that you'll get 1's and 0's (assuming you never repeat a flag for a class). The "main" query at the top of the statement simply turns the 1's and 0's into T's and F's.

Again, this requires you to know what your column names will be, but it's the only way I know how to do it without "PIVOT" being built in to the SQL language you are using. MS SQL might have a PIVOT built-in, so you might want to dig to find that.


This is not pretty and I generally don't like dynamically created SQL, but with an unknown list of flags, I'm not really sure how else you would do it. Additionally, you're right in that the PIVOT command expects an aggregate so I just used MAX. Yes, this is kind of hackish, but it does get the job done and will scale as new flags are added. I think this should work on 2005/2008 versions of SQL-SERVER. I'm not sure about 2003 as I don't know if it has the XML PATH command.

Declare @ColumnsIn varchar(max)
Declare @ColumnsIsNull varchar(max)
Declare @sql varchar(max)

Select @ColumnsIn = Stuff((Select Distinct ',[' + Flags + ']' From Classes For XML PATH('')),1,1,'')
Select @ColumnsIsNull = Stuff((Select Distinct ', IsNull([' + Flags + '], ''F'') as [' + Flags + ']' From Classes For XML PATH('')),1,1,'')

Set @sql = '
    Select 
        ClassName,
        Description,
        ' + @ColumnsIsNull + '
    FROM
    (
        Select
            Classes.ClassName,
            Classes.Description,
            Classes.Flags,
            ''T'' as HasFlag
        From
            Classes
    ) as Sub1
    Pivot (Max(HasFlag) For Flags in (' + @ColumnsIn + ')) as Sub2'

Execute(@sql)


SELECT classname
,description
,CASE
WHEN flags = 'F1'
  THEN 'T'
  ELSE 'F'
END f1
,CASE
WHEN flags = 'F2'
  THEN 'T'
  ELSE 'F'
END f2
... 
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜