2015-09-19 4 views
1

У меня есть 3 таблицыTSQL Pivot 3 Таблицы

Пользователи

ID, UserID, balance, name,  email 
1 Test1  5.44 Jan  [email protected] 
2 Test2  9.22 Ken  kenmail.com 

Модули

ID, ModuleID, Price, Active (bit) 
1  JAlert  2  1 
2  jFeed  1  1 
3  jCross  4  1 

Subs

ID, ModuleID, UserID, Timeline (all nvarchar, except ID) 
1  jAlert Test1 0A12 
2  jAlert Test2 B241 
4  jfeed  Test2 011A 

Мне нужно составить список всех пользователей и для каждого пользователя необходимо иметь в колонке Nam все активные ModuleID из модулей и в строке на временной шкале как

UserID Name Balance Jalert jFeed jCross 
Test1 Jan 5.44 0A12 Null Null 
Test2 Ken 9.22 B241 011A Null 

Я понял, что я должен используйте Pivot для перевода строки в колонку .. и прибегая к помощи вокруг, я нашел способ создания динамически головок колонок:

SELECT 
    @cols = ISNULL(@cols + ',','') + 
      QUOTENAME(ModuleID) 
FROM 
    (SELECT TOP 20 ModuleID 
    FROM modules 
    WHERE Active = '1' 
    ORDER BY SortOrder ASC) AS Columns; 

, но у меня есть проблемы с другим запросом:

SET @sql = N'SELECT UID, ' + @cols + 
    ' FROM (select ID, uid, timeline from subscriptions) a 
    PIVOT (count(id) for timeline IN (' + @cols + ')) AS p ' 

, который возвращает все нули, а параметр не имеет смысла ..

в то время как это, что кажется более разумным ...

SET @sql = N'SELECT UID, ' + @cols + 
    ' FROM (select ID, uid, timeline from subscriptions) a 
    PIVOT (count(id) for id IN (' + @cols + ')) AS p ' 

возвращает ошибку при переходе от nvarchar к Int

Проблема в том, что мне не нужна агрегация, но кажется, что для этой оси требуется такая функция.

Можете ли вы предложить решение или обходной путь?

Благодаря

ответ

1

Построить свой динамический запрос, как это:

'select * from 
    (select u.userid, u.name, u.balance, s.moduleid, s.timeline 
    from users u 
    join subs s on u.userid = s.userid)q 
pivot(max(timeline) for moduleid in(' + @cols + '))p' 

Это утверждение группирует вы результаты по 3 колонки u.userid, u.name, u.balance (принцип исключения). В столбцах вы получите все активные модули. В строках вы получите агрегацию временной шкалы для каждого пользователя или null, если нет такого модуля для пользователя.

+0

Отлично! работает очень хорошо .. также добавление некоторых других полей с подзапросами Спасибо – Joe

+0

Слишком быстро! :-( Что делать, если мне нужно получить только часть временной шкалы, например > 'SUBSTRING (временная шкала, датированная (m, CAST ('01 -01-2015 'в качестве даты),> CAST (GETDATE() AS DATE)), 12) в качестве временной шкалы , так как существует функция max() .. не позволяет мне извлечь часть строки. – Joe

+0

Вы можете делать свои вычисления в подзапросе 'q'. Я не могу получить то, что вы просите для. Лучше спросить об этом как о новом вопросе, поскольку текущий имеет полный ответ, основанный на текущих требованиях. –

Смежные вопросы