2013-09-10 23 views
2

我有一個由pageno int,groupid varchar(10)組成的表。表中的每一行都是不同的。可以有多個groupid和pageno組合。 pagenos的數量是未知的,並且groupids的數量是未知的。該數據可能是這樣的:動態數據透視表還是什麼?

pageno groupid 
101105 mpadilla 
101105 gentry 
100100 mpadilla 
100100 gentry 

我想有返回的結果集顯示pagenos爲列和諸組爲行和X在它們交叉(這意味着它存在着對您做生意/ GROUPID組合)。

我會使用sql的數據透視嗎?如果是這樣,請給我一個例子。如果沒有,請提供你的例子和解釋。我有點困惑。

回答

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) | 

編輯,如果你有,你要替換空值,然後我會創造列名這一項將被用於最終選擇列表中的第二個列表,它將包括​​3210來替換null。代碼將爲:

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 |  | 
+0

謝謝bluefeet。這與我最終的結果非常相似。你可以查看我的代碼並擴展它嗎?我現在想知道如何將NULLS更改爲空或其他文本以使結果更易於閱讀。現在我有很多NULLS,結果很混亂。 – user2766661

+0

@ user2766661看到我的編輯,您將創建第二列列表,將用於替換空值 – Taryn

+0

謝謝bluefeet,但我對如何將您的代碼轉換爲我的有點困惑。你能看看我的代碼,並給我一個關於如何使用合併的例子。我一直在尋找除你之外的很多例子,我仍然無法讓它與我的代碼一起工作。在我回答我最初的問題的地方看到我的代碼。再次感謝! – user2766661

-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 ('[email protected]+')) AS CustomizedPagesPerGroups' 
EXECUTE (@query)