SQL 服务器:Crosstab/Pivot 价目表

SQL Server : Crosstab/Pivot Price List

我花了 2 天的时间试图让它工作,但我没有接近解决这个问题。

我已将数据整合在一起以制作 PriceList 视图

| Category     | Product     | QtyFrom | QtyTo   | Price   |
------------------------------------------------------------
| Category#1   | Product#1   | 1       | 9       | 4.99    |
| Category#1   | Product#2   | 1       | 9       | 5.99    |
| Category#1   | Product#3   | 1       | 9       | 6.99    |
| Category#1   | Product#1   | 10      | 49      | 4.75    |
| Category#1   | Product#2   | 10      | 49      | 5.75    |
| Category#1   | Product#3   | 10      | 49      | 6.75    |
| Category#1   | Product#1   | 50      | 99      | 4.50    |
| Category#1   | Product#2   | 50      | 99      | 5.50    |
| Category#1   | Product#3   | 50      | 99      | 6.50    |
| Category#1   | Product#1   | 100     | 999     | 4.25    |
| Category#1   | Product#2   | 100     | 999     | 5.25    |
| Category#1   | Product#3   | 100     | 999     | 6.25    |
| Category#2   | Product#4   | 1       | 9       | 4.99    |
| Category#2   | Product#5   | 1       | 10      | 5.99    |
| Category#2   | Product#6   | 1       | 9       | 6.99    |
| Category#2   | Product#4   | 10      | 49      | 4.75    |
| Category#2   | Product#5   | 11      | 50      | 5.75    |
| Category#2   | Product#6   | 10      | 49      | 6.75    |
| Category#2   | Product#4   | 50      | 99      | 4.50    |
| Category#2   | Product#5   | 51      | 99      | 5.50    |
| Category#2   | Product#6   | 50      | 99      | 6.50    |

我需要交叉制表以生成价目表。最终结果将按需要 return 结果的单个类别查询

| Category#1   |  1  |  9  |  10  |  49  |  50  |  99  |
--------------------------------------------------------
| Product#1    |    4.99   |     4.75    |     4.50    |
| Product#2    |    5.99   |     5.75    |     5.50    |
| Product#3    |    6.99   |     6.75    |     6.50    |

或喜欢

| Category#2   |  1  |  9  |  1  |  10  |  10  |  49  |
--------------------------------------------------------
| Product#4    |    4.99   |             |     4.75    |
| Product#5    |           |     5.99    |             |
| Product#6    |    6.99   |             |     6.75    |

如您所见,根据输入数据的人员不同,他们可能会犯错并使组内的价格突破点错位。但我仍然需要 return 3 个最低的 QtyFrom/QtyTo 行(一旦我有了这些数据,我将生成一个单独的报告,仅显示每个类别的价格突破数量,以便他们可以 运行生成价目表并调整价格区间)

有些类别可能没有 3 次价格中断,而其他类别可能有更多。但我总是需要 3 列。

使用 SQL 服务器 2014

提前致谢。

您尝试过使用 conditional Aggregate

SELECT Product,
       Max(CASE WHEN QtyFrom >= 1 AND QtyTo <= 9 THEN Price END) [1 | 9],
       Max(CASE WHEN QtyFrom >= 10 AND QtyTo <= 49 THEN Price END) [10 | 49],
       Max(CASE WHEN QtyFrom >= 50 AND QtyTo <= 99 THEN Price END) [50 | 99]
FROM   Yourtable
WHERE  Category = 'Category#1'
GROUP  BY Product 

或使用Pivot。在数据透视源查询中,您需要创建范围列以在数据透视列列表中使用它。

SELECT *
FROM  (SELECT CONVERT(VARCHAR(50), QtyFrom) + ' | '
              + CONVERT(VARCHAR(50), QtyTo) AS Rang,
              Product,
              price
       FROM   Yourtable
       WHERE  Category = 'Category#1') a
      PIVOT (Max(price)
            FOR Rang IN ([1 | 9],
                         [10 | 49],
                         [50 | 99]))piv 

更新: 如果您不知道价格区间,请使用 Dynamic Pivot

DECLARE @cols VARCHAR(max)='',
        @sql  NVARCHAR(max)

SET @cols = (SELECT DISTINCT '[' + CONVERT(VARCHAR(50), QtyFrom) + ' | '
                             + CONVERT(VARCHAR(50), QtyTo) + '],'
             FROM   Yourtable
             WHERE  Category = 'Category#1'
             FOR xml path(''))

SELECT @cols = LEFT(@cols, Len(@cols) - 1)

SET @sql = 'SELECT *
    FROM  (SELECT CONVERT(VARCHAR(50), QtyFrom) + '' | ''
                  + CONVERT(VARCHAR(50), QtyTo) AS Rang,
                  Product,
                  price
           FROM   Yourtable
           WHERE  Category = ''Category#1'') a
          PIVOT (Max(price)
                FOR Rang IN (' + @cols + '))piv '

EXEC Sp_executesql  @sql