SQL Server 2012 Dynamic Pivot Table 具有多个子查询和行 'headers' - 这可以做到吗?

SQL Server 2012 Dynamic Pivot Table with multiple subqueries and row 'headers' - can this be done?

我被指派开发一个查询,该查询将导致 table 地区、地区和客户填充 A、B、C 列,其余列显示活动名称作为列 header(第 1 行)。管理层希望数据透视 table 的 body 中包含联系人姓名和联系人日期。像这样:

Region  |District   |ClientID   |Campaign1  |Campaign2  |Campaign3
========|===========|===========|===========|===========|===========
1       |A          |830        |   NULL    |   NULL    |   NULL        
========|===========|===========|===========|===========|===========
1       |A          |832        |Name One   |   NULL    |Name One   
        |           |           |Date       |           |Date           
========|===========|===========|===========|===========|===========
1       |A          |833        |   NULL    |   NULL    |   NULL    
========|===========|===========|===========|===========|===========
1       |A          |834        |   NULL    |   NULL    |   NULL    
========|===========|===========|===========|===========|===========
1       |A          |837        |Name Two   |   NULL    |   NULL    
        |           |           |Date       |           |           
========|===========|===========|===========|===========|===========
1       |A          |841        |   NULL    |   NULL    |   NULL    
========|===========|===========|===========|===========|===========
2       |K          |262        |   NULL    |   NULL    |   NULL        
========|===========|===========|===========|===========|===========
2       |L          |266        |   NULL    |   NULL    |   NULL                   
        |           |           |           |           |            
========|===========|===========|===========|===========|===========

我是新来的。我在 SQL 服务器方面相对处于初学者水平。我不确定 SQL Server 2012 的功能限制。

到目前为止,我已经能够从后面的查询中得到这些结果:

|ClientID   |Campaign1  |Campaign2  |Campaign3  |Campaign4  |
|===========|===========|===========|===========|===========|
|830        |   NULL    |   NULL    |   NULL    |   NULL    |
|===========|===========|===========|===========|===========|
|832        |Name One   |   NULL    |Name One   |Name One   | 
|===========|===========|===========|===========|===========|
|833        |   NULL    |   NULL    |   NULL    |   NULL    |
|===========|===========|===========|===========|===========|
|834        |   NULL    |   NULL    |   NULL    |   NULL    |
|===========|===========|===========|===========|===========|
|837        |Name Two   |   NULL    |   NULL    |   NULL    |
|===========|===========|===========|===========|===========|
|841        |   NULL    |   NULL    |   NULL    |   NULL    |
|===========|===========|===========|===========|===========|
|262        |   NULL    |   NULL    |   NULL    |   NULL    |
|===========|===========|===========|===========|===========|
|266        |   NULL    |   NULL    |   NULL    |Name Six   |
|===========|===========|===========|===========|===========|

当前查询:

IF Object_ID('tempdb.dbo.#temp') is not null
drop table dbo.#temp

SELECT * 
INTO #temp
FROM
   (
   SELECT MC.Region,MC.District,MS.ClientID,ML.CampaignName,MCL.ContactName
   FROM MnfstClient MC
   LEFT JOIN ManifestSummary MS on MC.ClientID=MS.ClientID      
   LEFT JOIN MnfstList ML on ML.FileDetailID=MS.FileID 
     and MS.ControlGroupFlag=0
   LEFT JOIN MnfstClientList MCL on MS.ClientID=MCL.ClientID 
     and ML.ListID=MCL.ListID
WHERE ML.InHomeDate Between '2016-04-01' and '2017-03-31'
GROUP By MC.Region,MC.District,MS.ClientID,ML.CampaignName,MCL.ContactName) A   
DECLARE @cols AS NVARCHAR(MAX),
        @query  AS NVARCHAR(MAX);
SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(c.CampaignName)
        FROM #temp c
        FOR XML PATH(''), TYPE
        ).value('.', 'NVARCHAR(MAX)') 
    ,1,1,'')
SET @query = 'SELECT ClientID, ' + @cols + ' from 
        (
            SELECT
                 Region
                 ,District 
                 ,ClientID
                 ,ContactName
                 ,CampaignName
            FROM #temp
       ) x
        PIVOT 
        (
             max(ContactName)
            for CampaignName in (' + @cols + ')
        ) p '
EXECUTE(@query)

这是我 运行 'SELECT INTO' 语句时 #temp 中的内容:

+--------+----------+----------+--------------+-------------+-------+
| Region | District | ClientID | CampaignName | ContactName | Date  |
+--------+----------+----------+--------------+-------------+-------+
|      1 | A        |      830 | Campaign1    | null        | Date  |
|      1 | A        |      830 | Campaign2    | null        | Date  |
|      1 | A        |      830 | Campaign3    | null        | Date  |
|      1 | A        |      832 | Campaign1    | Name One    | Date  |
|      1 | A        |      832 | Campaign2    | null        | Date  |
|      1 | A        |      832 | Campaign3    | Name One    | Date  |
|      1 | A        |      833 | Campaign1    | null        | Date  |
|      1 | A        |      833 | Campaign2    | null        | Date  |
|      1 | A        |      833 | Campaign3    | null        | Date  |
|      1 | A        |      834 | Campaign1    | null        | Date  |
|      1 | A        |      834 | Campaign2    | null        | Date  |
|      1 | A        |      834 | Campaign3    | null        | Date  |
|      1 | A        |      837 | Campaign1    | Name Two    | Date  |
|      1 | A        |      837 | Campaign2    | null        | Date  |
|      1 | A        |      837 | Campaign3    | null        | Date  |
|      1 | A        |      841 | Campaign1    | null        | Date  |
|      1 | A        |      841 | Campaign2    | null        | Date  |
|      1 | A        |      841 | Campaign3    | null        | Date  |
|      2 | K        |      262 | Campaign1    | null        | Date  |
|      2 | K        |      841 | Campaign2    | null        | Date  |
|      2 | K        |      841 | Campaign3    | null        | Date  |
|      2 | L        |      841 | Campaign1    | null        | Date  |
|      2 | L        |      841 | Campaign2    | null        | Date  |
|      2 | L        |      841 | Campaign3    | null        | Date  |
+--------+----------+----------+--------------+-------------+-------+

好了。如果我无法让查询结果看起来如我所愿,我将需要 运行 查询,将结果转储到 Excel 以及 table 地区、地区、客户并使用VLOOKUP。最终用户不能't/won那样做。因此,我的工作是每周 运行 查询,并进行 Excel 修改。 (而且,对我来说,工作=糟糕)

那么,答案是什么?能否达到想要的pivot的复杂度?

提前致谢!

看来您可以通过将 ContactNameDate 列连接在一起来获得所需的结果。一旦它们在您的子查询中连接起来,您将使用该新列来获得最终结果。将您的查询更改为:

SET @query = 'SELECT Region, District, ClientId, ' + @cols + ' 
              from 
              (
                  SELECT
                       Region
                       ,District 
                       ,ClientID
                       ,ContactName = ContactName + '' '' + Date -- concatenated column
                       ,CampaignName
                  FROM #yourquery
             ) x
              PIVOT 
              (
                   max(ContactName)
                  for CampaignName in (' + @cols + ')
              ) p '
              
EXECUTE(@query)

See Demo 同时具有静态和动态版本。