2015-11-05 91 views
2

我有这样结果的表:动态枢轴多个列

EMP_ID | Boss_ID | Boss_Name | Specialty 

    1001  001  John    sql 
    1001  001  John    c# 
    1002  002  James   c++ 
    1002  003  Sarah   sql 
    1002  003  Sarah   python 
    1003  004  Jesse   networking 

雇员可以具有可以有多个特色的多个凸起部。

我需要动态调整数据以便每位员工有一行。我需要展示员工,所有老板和他们的第一线专业。

我能够使用动态数据透视和显示多个老板部分,但我不确定如何显示他们的专业名称旁边。

以下是我有:

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

    select t.EMP_ID 
     ,t.Boss_Name 
     ,t.Boss_ID 
     ,t.Specialty 
     ,'BOSS' + '_' + cast(ROW_NUMBER() OVER (PARTITION BY t.EMP_ID ORDER BY t.BOSS_ID asc) AS VARCHAR) AS b_rn 
     ,'SPEC' + '_' + cast(ROW_NUMBER() OVER (PARTITION BY t.Specialty ORDER BY t.BOSS_ID asc) AS VARCHAR) AS spec_rn 
    INTO #work 
    from #testing t 

SELECT @cols = STUFF(
        (SELECT DISTINCT TOP 100 PERCENT '],[' + w.b_rn 
        FROM #work w 
        ORDER BY '],[' + w.b_rn 
        FOR XML PATH('') 
       ), 1, 2, '' 
       ) + ']' 

PRINT @cols 

SET @query = N' SELECT EMP_ID,' + @cols + N' 
      INTO ##work_results FROM 
       (
        SELECT EMP_ID 
         ,Boss_Name 
         ,b_rn 

        FROM #work 
       ) AS sourcetable 
PIVOT 
(
max(Boss_Name) for b_rn IN ('+ @cols + N') 
) AS pivot_table' 


execute(@query) 

select * from ##work_results 

这给了我:

EMP_ID | BOSS_1 | BOSS_2 | BOSS_3 
1001  John  John   NULL 
1002  James  Sarah   Sarah 
1003  Jesse  NULL   NULL 

我所真正需要的是结果是这样的:

EMP_ID | Boss_1 | Specialty_1 | Boss_2 | Specialty_1 

    1001  John  sql 
    1002  James c++   Sarah  sql 
    1003  Jesse networking 

我已经看过其他职位,但他们不是我所期待的。

任何帮助将是美好的。

谢谢!

+0

这是枢轴的限制之一。它不能旋转多列。我更愿意使用动态交叉标签,即使只有一列。对我来说,语法不那么呆板,甚至可以享受轻微的性能优势。这里有一篇很好的文章解释了它的工作原理。 http://www.sqlservercentral.com/articles/Crosstab/65048/ –

+0

我会阅读那篇文章。谢谢回复! – jw133

+0

也许你可以将'pivot_table'加入'#testing'来获得每位老板的特色。不过,您必须为每个老板专栏加入一次。 –

回答

0

你可能会这样:

诀窍是,连接你的值。因此,只有一列,与枢没有问题... ...

DECLARE @tbl TABLE(EMP_ID INT,Boss_ID INT,Boss_Name VARCHAR(100),Specialty VARCHAR(100)); 
INSERT INTO @tbl VALUES 
(1001,001,'John','sql') 
,(1001,001,'John','c#') 
,(1002,002,'James','c++') 
,(1002,003,'Sarah','sql') 
,(1002,003,'Sarah','python') 
,(1003,004,'Jesse','networking'); 

SELECT p.* 
FROM 
(
    SELECT tbl.EMP_ID 
      --If you need your Bosses in the given order you must add a sort crit to your original table! 
      ,'Column_' + CAST(ROW_NUMBER() OVER(PARTITION BY tbl.EMP_ID ORDER BY tbl.EMP_ID) AS VARCHAR(MAX)) AS ColumnName 
      ,tbl.Boss_Name + ' (' + tbl.Specialty + ')' AS Concatenated 
    FROM @tbl AS tbl 
) AS ToBePivoted 
PIVOT 
(
    MIN(Concatenated) FOR ColumnName IN(Column_1,Column_2,Column_3 /*add maximum here*/) 
) As p 

结果

1001 John (sql)   John (c#)  NULL 
1002 James (c++)   Sarah (sql) Sarah (python) 
1003 Jesse (networking) NULL   NULL 

如果您需要的值分开的另一招是,来连接在XML格式的所有需要​​的列(但不XML型!)。

由于串联是XML格式,因此只需通过索引提取元素就很容易。

DECLARE @tbl TABLE(EMP_ID INT,Boss_ID INT,Boss_Name VARCHAR(100),Specialty VARCHAR(100)); 
INSERT INTO @tbl VALUES 
(1001,001,'John','sql') 
,(1001,001,'John','c#') 
,(1002,002,'James','c++') 
,(1002,003,'Sarah','sql') 
,(1002,003,'Sarah','python') 
,(1003,004,'Jesse','networking'); 

SELECT p.EMP_ID 

     ,CAST(Column_1 AS XML).value('x[1]','int') AS BossID_1 
     ,CAST(Column_1 AS XML).value('x[2]','varchar(max)') AS BossName_1 
     ,CAST(Column_1 AS XML).value('x[3]','varchar(max)') AS specialty_1 

     ,CAST(Column_2 AS XML).value('x[1]','int') AS BossID_2 
     ,CAST(Column_2 AS XML).value('x[2]','varchar(max)') AS BossName_2 
     ,CAST(Column_2 AS XML).value('x[3]','varchar(max)') AS specialty_2 

     ,CAST(Column_3 AS XML).value('x[1]','int') AS BossID_3 
     ,CAST(Column_3 AS XML).value('x[2]','varchar(max)') AS BossName_3 
     ,CAST(Column_3 AS XML).value('x[3]','varchar(max)') AS specialty_3 
     /*Add a maximum here*/ 
FROM 
(
    SELECT tbl.EMP_ID 
      --If you need your Bosses in the given order you must add a sort crit to your original table! 
      ,'Column_' + CAST(ROW_NUMBER() OVER(PARTITION BY tbl.EMP_ID ORDER BY tbl.EMP_ID) AS VARCHAR(MAX)) AS ColumnName 
      ,'<x>' + CAST(tbl.Boss_ID AS VARCHAR(10)) + '</x><x>' + tbl.Boss_Name + '</x><x>' + tbl.Specialty + '</x>' AS ValuesAsXML 
    FROM @tbl AS tbl 
) AS ToBePivoted 
PIVOT 
(
    MIN(ValuesAsXML) FOR ColumnName IN(Column_1,Column_2,Column_3 /*add maximum here*/) 
) As p 

结果

1001 1 John sql   1  John c#  NULL NULL NULL 
1002 2 James c++   3  Sarah sql  3  Sarah python 
1003 4 Jesse networking NULL NULL NULL NULL NULL NULL 
+0

ha我起初尝试了连接方法,但最终用户希望在自己的专栏中使用专业。至于你的第二种方法,这是有效的,但那是如果我知道将有列的数量。老板的数量是可变的,所以我不能在这里列出列。 (道歉,如果我失去了一些东西)谢谢! – jw133

+0

@ jw133,好吧,最终用户是国王;-)那么XML技巧呢? – Shnugo

+0

这意味着更多的是一个问题。对于XML技巧,我对如何动态设置它有点困惑。你发布的例子效果很好,但只有当我知道有多少列(在这种情况下是3)的时候。 – jw133