简体   繁体   English

SQL Server 2008 CrossTab等效项

[英]SQL Server 2008 CrossTab equivalent

Afternoon Guys n Girls. 下午,男生。

Using SQL SERVER 2008. 使用SQL SERVER 2008。

I have a table called userModList . 我有一个名为userModList的表。 Its contains fields, " USERID "(int), " ModuleID "(int), and " Passed "(bin). 它包含字段“ USERID ”(int),“ ModuleID ”(int)和“ Passed ”(bin)。 example data; 示例数据;

USERID    ModuleID    Passed
134         12          1
134         10          0
134         18          1

What i would like to display is: 我想显示的是:

USERID    (moduleNum12)     (ModuleNum10)     (ModuleNum18)
 134           1                  0                 1

Now In MS access all you would do is create a cross query , so User ID becomes the row , Module numbers become the Columns and Passed is the values (binary 1 or 0). 现在,在MS Access中,您要做的就是创建一个交叉查询 ,因此User ID成为row ,Module number成为Columns ,Passed是 (二进制1或0)。

I would like to do this server Side in a Stored Procedure, but I have never Attempted cross tabbing data. 我想在存储过程中执行此服务器端,但是我从未尝试过交叉制表数据。

Also The moduleID is dynamic meaning there may be 3 modules for a user or 17. So it needs to be dynamic, not sure if this makes a big difference? 另外, moduleID是动态的,这意味着一个用户可能有3个模块,也可能是17个。因此,它必须是动态的,不确定是否有很大的不同?

Anyway some help on this would be great, ill try and provide some sample code Of what I will try, But as it stands I'm stuck as to where to start. 无论如何,在此方面提供一些帮助非常有用,请尝试提供一些我将尝试使用的示例代码,但是就目前的情况而言,我对于从哪里开始感到困惑。

many thanks guys! 非常感谢你们!

There are a few different ways that you can do this in SQL Server you can use the PIVOT function: 在SQL Server中,可以使用几种不同的方法来使用PIVOT函数:

select userid,
  [12] moduleNum12,
  [10] moduleNum10,
  [18] moduleNum18
from
(
  select userid, moduleid, cast(passed as int) passed
  from yourtable
) d
pivot
(
  max(passed)
  for moduleId in ([12], [10], [18])
) piv;

See Demo 观看演示

Or you can use an aggregate function with a CASE expression: 或者,您可以将聚合函数与CASE表达式一起使用:

select userid,
  max(case when moduleid = 12 then cast(passed as int) end) moduleNum12,
  max(case when moduleid = 10 then cast(passed as int) end) moduleNum10,
  max(case when moduleid = 18 then cast(passed as int) end) moduleNum18
from yourtable
group by userid;

See Demo . 参见演示

The above work great if the values are known nut if you have unknown values, then you will need to use dynamic SQL: 如果您知道未知的值,则上面的方法非常有用,如果您知道未知的值,那么您将需要使用动态SQL:

DECLARE @cols AS NVARCHAR(MAX),
    @colsAlias AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(ModuleID) 
                    from yourtable
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

select @colsAlias = STUFF((SELECT distinct ', ' + QUOTENAME(ModuleID) +' as moduleNum'+cast(ModuleID as varchar(10))
                    from yourtable
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT userid,' + @colsAlias + ' 
            from
            (
               select userid, moduleid, cast(passed as int) passed
               from yourtable 
            ) d
            pivot 
            (
                max(passed)
                for moduleid in (' + @cols + ')
            ) p '

execute(@query)

See Demo 观看演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM