2009-11-03 6 views
1

У меня есть представление SQL со следующими данными: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, но все они либо для СУММ, либо для других агрегатных функций. Не уверен, что любой из них будет работать так, как я тоже не буду.

+0

Какая версия SQL Server и что вы пробовали? –

ответ

0

выберите имя_класса, описание, случай, когда флаги = 'F1', затем 'T' еще 'F' конец F1, случай, когда флаг = 'F2', затем 'T' еще 'F' конец F2, ...

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 (при условии, что вы никогда не повторять флаг для класса). «Основной» запрос в верхней части утверждения просто превращает 1 и 0 в T и F.

Опять же, это требует, чтобы вы знали, какими будут ваши имена столбцов, но это единственный способ, которым я знаю, как это сделать без «PIVOT», встроенного в язык SQL, который вы используете. MS SQL может иметь встроенный PIVOT, поэтому вам может понадобиться найти его.

+0

Я не знаю, что мои Флаги, поскольку конечный пользователь имеет возможность добавлять, обновлять или удалять флаги и устанавливать связь с любым классом, который им нужен (например, пользователь может добавить новый флаг, скажем F101 или переименовать существующий флаг F1 в F01). Я использую SQL Express 2005 – Deepak

+0

Вот скверный взлом: если у вас есть возможность генерировать SQL во время выполнения, вы можете запросить свою таблицу для всех доступных имен флагов, а затем сгенерировать оператор SQL с помощью столбцов (Sum (Case When Flags) ...) автоматически генерируется из кода. Это заставляет меня чувствовать себя грязным, думая об этом, но это сработает, если бы у вас был код для работы. –

1

Генри Фао находится на правильном пути - но вам нужно «сгладить» ряды группой.

 
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 

В столбце F1 каждой группы должно быть только «Т». Другие строки будут иметь нуль в столбце T1. Функция max() игнорирует нули и возвращает «T» - если она есть.

0

Это некрасиво, и мне обычно не нравится динамически созданный SQL, но с неизвестным списком флагов я не совсем уверен, как еще вы это сделаете. Кроме того, вы правы в том, что команда PIVOT ожидает агрегата, поэтому я просто использовал MAX. Да, это своего рода хакерство, но оно выполняет свою работу и будет масштабироваться по мере добавления новых флагов. Я думаю, что это должно работать над версиями SQL Server SERVER 2005/2008. Я не уверен в 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)