查询以多列为中心

时间:2017-06-15 20:33:52

标签: sql-server sql-server-2008-r2 pivot

我有一个产生所需输出的查询,但没有正确的布局。我需要将一些列作为一个组进行轮转,但无法弄清楚如何进行。

查询如下:

SELECT Line.DocumentName
      ,Package.PackageName
      ,Package.ContainerCount
      ,Package.PageCount
      ,m.Name Media
  FROM Invoice i
    JOIN Section s ON i.InvoiceDate = s.InvoiceDate
    JOIN Line l ON s.InvoiceDate = l.InvoiceDate AND s.DocumentTypeID = l.DocumentTypeID
    JOIN Package p ON l.InvoiceDate = p.InvoiceDate AND l.DocumentTypeID = p.DocumentTypeID AND l.DocumentDate = p.DocumentDate
    JOIN MediaType m ON p.MediaTypeID = m.Id
  WHERE i.InvoiceDate = '6/1/2017';

返回:

|varchar(100)        |char(2)    |int           |int      |varchar(10)|
|--------------------|-----------|--------------|---------|-----------|
|DocumentName        |PackageName|ContainerCount|PageCount|Media      |
|--------------------|-----------|--------------|---------|-----------|
|Invoices17_05_26.xml|01         |          1758|     2024|A          |
|Invoices17_05_26.xml|30         |           382|     1728|Email      |
|Invoices17_05_30.xml|01         |          2757|     3336|A          |
|Invoices17_05_30.xml|30         |           626|     2101|Email      |
|Credits17_05_01.xml |01         |          1346|     1488|A          |
|Credits17_05_01.xml |30         |           390|      451|Email      |
|Credits17_05_08.xml |01         |             0|        0|C          |
|Credits17_05_08.xml |30         |           353|      408|Email      |
|Stmts-17_05_01.xml  |01         |         14796|    15299|B          |
|Stmts-17_05_01.xml  |30         |          2888|     3267|Email      |

但是,我需要输出具有这种布局:

|DocumentName        |01 ContainerCount|01 PageCount|01 Media|30 ContainerCount|30 PageCount|30 Media|
|--------------------|-----------------|------------|--------|-----------------|------------|--------|
|Invoices17_05_26.xml|             1758|        2024|A       |              382|        1728|Email   |
|Invoices17_05_30.xml|             2757|        3336|A       |              626|        2101|Email   |
|Credits17_05_01.xml |             1346|        1488|A       |              390|         451|Email   |
|Credits17_05_08.xml |                0|           0|C       |              353|         408|Email   |
|Stmts-17_05_01.xml  |            14796|       15299|B       |             2888|        3267|Email   |

我尝试过以下各种变体,但无济于事:

2 个答案:

答案 0 :(得分:1)

我不清楚你是否需要动态(即众多的PackageName)

最简单的方法可能是将初始查询包装在一个最终的条件聚合中

示例

Select DocumentName
      ,[01 ContainerCount] = sum(case when PackageName='01' then ContainerCount end)
      ,[01 PageCount]      = sum(case when PackageName='01' then PageCount end)
      ,[01 Media]          = max(case when PackageName='01' then Media end)
      ,[30 ContainerCount] = sum(case when PackageName='30' then ContainerCount end)
      ,[30 PageCount]      = sum(case when PackageName='30' then PageCount end)
      ,[30 Media]          = max(case when PackageName='30' then Media end)
 From  (
        SELECT Line.DocumentName
              ,Package.PackageName
              ,Package.ContainerCount
              ,Package.PageCount
              ,m.Name Media
          FROM Invoice i
            JOIN Section s ON i.InvoiceDate = s.InvoiceDate
            JOIN Line l ON s.InvoiceDate = l.InvoiceDate AND s.DocumentTypeID = l.DocumentTypeID
            JOIN Package p ON l.InvoiceDate = p.InvoiceDate AND l.DocumentTypeID = p.DocumentTypeID AND l.DocumentDate = p.DocumentDate
            JOIN MediaType m ON p.MediaTypeID = m.Id
          WHERE i.InvoiceDate = '6/1/2017'
       ) A
 Group By DocumentName

<强>返回

enter image description here

答案 1 :(得分:1)

试试这个......
它支持多个列,但不是动态的

SELECT 
DocumentName
, [01 ContainerCount] = SUM([P1CC1])
, [01 PageCount] = SUM([P1PC1])
, [01 Media] = MAX([P1M1])
, [30 ContainerCount] = SUM([P30CC2])
, [30 PageCount] = SUM([P30PC2])
, [30 Media] = MAX([P30M2])
FROM (

SELECT 
    A.DocumentName AS DocumentName, 
    ContainerCount,
    [PageCount], 
    Media
    ,A.PackageName + 'CC' + CAST(DENSE_RANK() OVER (PARTITION BY A.DocumentName ORDER BY A.PackageName ASC) AS NVARCHAR) AS [PkgNumberCC]
    ,A.PackageName + 'PC' + CAST(DENSE_RANK() OVER (PARTITION BY A.DocumentName ORDER BY A.PackageName ASC) AS NVARCHAR) AS [PkgNumberPC]
    ,A.PackageName + 'M' + CAST(DENSE_RANK() OVER (PARTITION BY A.DocumentName ORDER BY A.PackageName ASC) AS NVARCHAR) AS [PkgNumberM]
    FROM (
        SELECT Line.DocumentName
              ,Package.PackageName
              ,Package.ContainerCount
              ,Package.PageCount
              ,m.Name Media
          FROM Invoice i
            JOIN Section s ON i.InvoiceDate = s.InvoiceDate
            JOIN Line l ON s.InvoiceDate = l.InvoiceDate AND s.DocumentTypeID = l.DocumentTypeID
            JOIN Package p ON l.InvoiceDate = p.InvoiceDate AND l.DocumentTypeID = p.DocumentTypeID AND l.DocumentDate = p.DocumentDate
            JOIN MediaType m ON p.MediaTypeID = m.Id
          WHERE i.InvoiceDate = '6/1/2017'
    ) A
) AS query
PIVOT (MAX(ContainerCount)
      FOR [PkgNumberCC] IN ([P1CC1],[P30CC2])) AS Pivot1
PIVOT (MAX([PageCount])
      FOR [PkgNumberPC] IN ([P1PC1],[P30PC2])) AS Pivot2
PIVOT (MAX(Media)
      FOR [PkgNumberM] IN ([P1M1],[P30M2])) AS Pivot3
GROUP BY
  DocumentName
ORDER BY DocumentName