1

我有一个包含以下数据的 SQL 视图:

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

我想要这样的结果:

ClassName    Description    F1   F2  F3  F4  F6   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

我试图查找 Pivot 示例,但所有这些示例都用于 SUM 或其他聚合函数。不确定其中任何一个是否会起作用,因为我也没有这样做。

4

4 回答 4

1

Henry Fao 走在了正确的轨道上——但你必须用 group by 来“压平”这些行。

选择 ClassName 作为 ClassName, 选择 Description 作为 Description
   , 合并(max(F1), 'F') 作为 F1
   , 合并(max(F2), 'F') 作为 F2
   , ETC
 从 (
        选择类名,描述
           , 如果 flags = 'F1' then 'T' else null end as F1
           , 如果 flags = 'F2' then 'T' else null end as F2
           等等
        来自 tbl
       ) 作为 t
  按类名、描述分组

每组的 F1 列中应该只有一个“T”。其他行在 T1 列中将为空。max() 函数忽略空值并将返回 'T' - 如果有的话。

于 2009-11-03T19:59:00.680 回答
0

这并不漂亮,而且我通常不喜欢动态创建的 SQL,但是由于标志列表未知,我不太确定您还会怎么做。此外,您说得对,因为 PIVOT 命令需要一个聚合,所以我只使用了 MAX。是的,这有点骇人听闻,但它确实完成了工作,并且会随着新标志的添加而扩展。我认为这应该适用于 2005/2008 版本的 SQL-SERVER。我不确定 2003 年是否有 XML PATH 命令。

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)
于 2009-11-04T07:10:53.013 回答
0

选择类名,描述,当 flags = 'F1' 然后 'T' else 'F' end F1, case when flags = 'F2' then 'T' else 'F' end F2, ...

于 2009-11-03T19:40:58.620 回答
0

我相信 MS SQL Server 支持数据透视表,但我不知道该怎么做。当我必须在 MySQL 中透视数据时,我使用 Sum 和 Case。但是,这仅在您事先知道列名将是什么时才有效。这是我可以做到的:

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

在上面的代码中,子查询将产生你想要的输出,除了你会得到 1 和 0(假设你从不重复一个类的标志)。语句顶部的“main”查询只是将 1 和 0 转换为 T 和 F。

同样,这需要您知道您的列名是什么,但这是我知道如何做到这一点的唯一方法,而您正在使用的 SQL 语言中没有内置“PIVOT”。MS SQL 可能有一个内置的 PIVOT,所以你可能想去挖掘它。

于 2009-11-03T19:46:21.933 回答