2

我有一个由 pageno int、groupid varchar(10) 组成的表。表中的每一行都是不同的。可以有多个 groupid 和 pageno 组合。pagenos 的数量是未知的,groupids 的数量是未知的。数据可能如下所示:

pageno groupid
101105 mpadilla
101105 gentry
100100 mpadilla
100100 gentry

我希望返回一个结果集,将 pagenos 显示为列,将 groupids 显示为行,以及它们相交的 x(这意味着它存在于该 pageno/groupid 组合中)。

我会为此使用sql pivot吗?如果是这样,请给我一个例子。如果没有,请提供您的示例和解释。我有点困惑。

4

2 回答 2

2

您的要求并不完全清楚,但如果我理解您的问题,您可以使用PIVOT函数来获得结果。

如果您的查询数量有限,则此查询的基本语法如下pagenos

select groupid, [101105], [100100]
from
(
  select pageno, groupid, 
    flag = 'X'
  from yourtable
) d
pivot
(
  max(flag)
  for pageno in ([101105], [100100])
) piv;

请参阅SQL Fiddle with Demo

然后,如果您有未知数量的值,则需要使用动态 SQL:

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

select @cols = STUFF((SELECT ',' + QUOTENAME(pageno) 
                    from yourtable
                    group by pageno
                    order by pageno
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT groupid, ' + @cols + ' 
            from 
            (
              select pageno, groupid, 
                flag = ''X''
              from yourtable
            ) x
            pivot 
            (
                max(flag)
                for pageno in (' + @cols + ')
            ) p '

execute sp_executesql @query;

请参阅SQL Fiddle with Demo。两个版本都会给出结果:

|  GROUPID | 100100 | 101105 |
|   gentry |      X |      X |
| mpadilla |      X |      X |
|     test |      X | (null) |

编辑,如果您有要替换的空值,那么我将创建第二个列名列表,该列表将用于最终选择列表,它将包括coalesce替换空值。代码将是:

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

select @cols = STUFF((SELECT ',' + QUOTENAME(pageno) 
                    from yourtable
                    group by pageno
                    order by pageno
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

select @colsNull = STUFF((SELECT ', coalesce(' + QUOTENAME(pageno) +', '''') as '+QUOTENAME(pageno)
                    from yourtable
                    group by pageno
                    order by pageno
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT groupid, ' + @colsNull + ' 
            from 
            (
              select pageno, groupid, 
                flag = ''X''
              from yourtable
            ) x
            pivot 
            (
                max(flag)
                for pageno in (' + @cols + ')
            ) p '

execute sp_executesql @query;

请参阅SQL Fiddle with Demo。结果将是:

|  GROUPID | 100100 | 101105 |
|   gentry |      X |      X |
| mpadilla |      X |      X |
|     test |      X |        |
于 2013-09-11T20:34:03.150 回答
-1

我回答了我自己的问题。我所做的是在我的原始表格中添加了一个名为自定义的附加列。此列仅包含每个自定义页面的 x。我知道有点多余,但数据透视表似乎需要 3 列。所以这是我想出并工作的动态代码:

DECLARE @query VARCHAR(4000), @groupids VARCHAR(8000)
SELECT @groupids = STUFF(( SELECT DISTINCT 
    '],[' + LTRIM(groupid) 
    FROM DistinctPages 
    ORDER BY '],[' + LTRIM(groupid)
    FOR XML PATH('')
    ), 1,2, '') + ']'   
SET @query =
'SELECT * FROM (SELECT pageno, groupid, customized FROM DistinctPages)t
PIVOT (MAX(customized) FOR groupid
IN ('+@groupids+')) AS CustomizedPagesPerGroups'
EXECUTE (@query)
于 2013-09-11T20:35:48.073 回答