0

我想将此结果中的数据放在列而不是行中。比如:2011_1 = 某个值,2011_2 = 某个值,...

SELECT      
        ls.Year,
        ls.Month, 
        lsq.Quantity
FROM    Log_Sales ls
        INNER JOIN Log_SalesQuantity lsq ON ls.Id = lsq.LogSalesId AND lsq.SaleStatisticTypeId = 1
WHERE   (ls.ProductId = 57983) AND
        (ls.BranchId = 1) AND           
        (ls.Year in (2011,2012,2013))

现在我得到这个结果:

Year    Month   Quantity
2011    1   9220
2011    2   10211
2011    3   7269
2011    4   7050
2011    5   8543
2011    6   7539
2011    7   6103
2011    8   8905
2011    9   5588
2011    10  5840
2011    11  8041
2011    12  5991
2012    1   11233
2012    2   2829
2012    3   4440
2012    4   7842
2012    5   8557
2012    6   11299
2012    7   10560
2012    8   8350
2012    9   7627
2012    10  9511
2012    11  5293
2012    12  7030
2013    1   6148
2013    2   2774
2013    3   3737
2013    4   2350
2013    5   4016
2013    6   2300

当我尝试使用 pivot 时,我得到了这个查询:

SELECT  [1] as '2013_1', [2]as '2013_2', [3]as '2013_3', [4]as '2013_4', [5]as '2013_5', [6]    
as '2013_6', [7]as '2013_7', [8]as '2013_8', [9]as '2013_9', [10]as '2013_10', [11]as '2013_11', 
[12]as '2013_12'
FROM
(SELECT     ls.Month, 
        lsq.Quantity
FROM    Log_Sales ls
        INNER JOIN Log_SalesQuantity lsq ON ls.Id = lsq.LogSalesId AND  
lsq.SaleStatisticTypeId = 1
WHERE   (ls.ProductId = 57983) AND
        (ls.BranchId = 1) AND           
        (ls.Year = 2013) ) AS SourceTable
PIVOT
(
sum(Quantity)
FOR [Month] IN ([1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12])
) AS PivotTable;

2013_1   2013_2 2013_3  2013_4  2013_5  2013_6  2013_7  2013_8  2013_9  2013_10 2013_11 2013_12
6148    2774    3737    2350    4016    2300    NULL    NULL    NULL    NULL    NULL    NULL

什么已经很好了,但我想拥有三年的活力。现在是 2011、2012、2013,但明年将是 2012、2013、2014。

获得此结果的最佳方法是什么?也许还有其他解决方案然后枢轴?请记住,这部分是大型、更复杂的查询。

4

2 回答 2

0

首先,您需要生成列列表,使它们成为动态的,然后使用此生成的列表进行透视。

    DECLARE @listStr VARCHAR(MAX) 
    SELECT @listStr = COALESCE(@listStr+',[' ,'[') + src.[Month] + ']'
    FROM (SELECT      
                cast(ls.Year as varchar)+ cast(ls.Month as varchar) as [Month]
        FROM    Log_Sales ls
                INNER JOIN Log_SalesQuantity lsq ON ls.Id = lsq.LogSalesId AND lsq.SaleStatisticTypeId = 1
        WHERE   (ls.ProductId = 57983) AND
                (ls.BranchId = 1) AND           
                (ls.Year in (2011,2012,2013))) as src
    select @listStr

    DECLARE @query VARCHAR(8000)
    SET @query = 'SELECT * FROM
    (
    SELECT      
                cast(ls.Year as varchar)+cast(ls.Month as varchar) as [Month], 
                lsq.Quantity
        FROM    Log_Sales ls
                INNER JOIN Log_SalesQuantity lsq ON ls.Id = lsq.LogSalesId AND lsq.SaleStatisticTypeId = 1
        WHERE   (ls.ProductId = 57983) AND
                (ls.BranchId = 1) AND           
                (ls.Year in (2011,2012,2013))
    )t
    PIVOT 
    (
    SUM(t.Quantity) FOR [Month]
    IN ('+@listStr+')
    ) pvt'

    Execute(@query)
于 2013-06-14T09:07:34.500 回答
0

我用这个sqlfiddle来验证。我添加了年份列和动态位置

SELECT year, [1] as 'jan', [2]as 'feb', [3]as 'mrt', [4]as 'apr', 
       [5] as 'may', [6] as 'jun', [7]as 'jul', [8] as 'aug', 
       [9]as 'sep', [10]as 'oct', [11]as 'nov',[12]as 'dec'
FROM
  (SELECT     ls.Month, 
              ls.Quantity,
              ls.Year
   FROM    Log_Sales ls
   WHERE   ls.Year > Year(GetDate()) -3 
   AND     ls.Year <= Year(GetDate())
  ) AS SourceTable
  PIVOT
  (
    sum(Quantity)
    FOR [Month] IN ( [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12])
  ) AS PivotTable
于 2013-06-14T09:28:19.597 回答