整个数据透视表

TSQL Pivot 3 Tables

我有3张桌子

用户

ID, UserID, balance,  name,     email 
1    Test1      5.44    Jan     jan@mail.com
2    Test2      9.22    Ken     kenmail.com

模块

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

订阅者

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

我需要制作一个包含所有用户的列表,对于每个用户,需要将来自模块的所有活动模块 ID 作为列 Nam,并在行中包含时间线 喜欢

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 '

returns全为零,但参数没有意义..

虽然这看起来更合理...

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

returns 从 nvarchar 转换为 int

时出错

问题是我不需要聚合,但 pivot 似乎需要这样的功能..

您能提出解决方案或解决方法吗?

谢谢

像这样构造您的动态查询:

'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。