在SQL Server中创建Excel数据透视表之类的Pivot查询

时间:2018-06-28 19:06:48

标签: sql sql-server pivot pivot-table

我正在尝试将Excel数据透视表转换为SQL查询,因此,与其直接从SQL Server数据库中提取数据,然后在Excel中手动创建数据透视表,不如直接在SQL中创建数据透视表查询。

以下是我的datapivot table

的示例

我被困在如何完成我的SQL查询中,我的开始是:

SELECT [Brand],[Location],[Qty],[Price] FROM ShipmentsTable 
PIVOT 
(
 SUM(Qty),SUM([Price])
 FOR [MFG Location] IN ... --not sure what to add here
)

任何建议,我应该如何更新我的查询?

1 个答案:

答案 0 :(得分:1)

您可以尝试使用CASE WHENSUM函数来实现它。

SELECT Brand,
       SUM(CASE WHEN Location = 'Austria' THEN qty END) 'Austria_qty',
       SUM(CASE WHEN Location = 'Austria' THEN Price  END) 'Austria_totle',
       SUM(CASE WHEN Location = 'France' THEN qty  END) 'France_qty',
       SUM(CASE WHEN Location = 'France' THEN Price END)'France_totle',
       SUM(CASE WHEN Location = 'Germany' THEN qty END) 'Germany_qty',
       SUM(CASE WHEN Location = 'Germany' THEN Price END)'Germany_totle',
       SUM(CASE WHEN Location = 'Italy' THEN qty END) 'Italy_qty',
       SUM(CASE WHEN Location = 'Italy' THEN Price END) 'Italy_totle'
FROM T
GROUP BY Brand

sqlfiddle:http://sqlfiddle.com/#!18/90e75/17

结果

|   Brand | Austria_qty |      Austria_totle | France_qty | France_totle | Germany_qty | Germany_totle | Italy_qty | Italy_totle |
|---------|-------------|--------------------|------------|--------------|-------------|---------------|-----------|-------------|
|   Apple |           1 |            1351.16 |          1 |         9.96 |           2 |       1583.85 |         1 |     1053.83 |
|  Huawei |           1 |             744.67 |     (null) |       (null) |           2 |     207704.86 |    (null) |      (null) |
|  Lenovo |           2 |            1184.21 |          2 |      1420.43 |           2 |       3454.91 |    (null) |      (null) |
|   Nokia |      (null) |             (null) |          1 |       796.03 |      (null) |        (null) |         1 |      538.41 |
| Samsung |      (null) |             (null) |          1 |      3327.14 |      (null) |        (null) |         1 |        9.09 |

修改

我看到了你的承诺

您可以尝试使用UNION ALL组合totle查询和Sum查询

;WITH CTE(Brand,Austria_qty,Austria_totle,France_qty,France_totle,Germany_qty,Germany_totle,Italy_qty,Italy_totle) 
AS (
  SELECT Brand,
         SUM(CASE WHEN Location = 'Austria' THEN qty END) 'Austria_qty',
         SUM(CASE WHEN Location = 'Austria' THEN Price  END) 'Austria_totle',
         SUM(CASE WHEN Location = 'France' THEN qty  END) 'France_qty',
         SUM(CASE WHEN Location = 'France' THEN Price END)'France_totle',
         SUM(CASE WHEN Location = 'Germany' THEN qty END) 'Germany_qty',
         SUM(CASE WHEN Location = 'Germany' THEN Price END)'Germany_totle',
         SUM(CASE WHEN Location = 'Italy' THEN qty END) 'Italy_qty',
         SUM(CASE WHEN Location = 'Italy' THEN Price END) 'Italy_totle'
  FROM T
  GROUP BY Brand
)

SELECT Brand,
    Austria_qty,
    Austria_totle,
    France_qty,
    France_totle,
    Germany_qty,
    Germany_totle,
    Italy_qty,
    Italy_totle 
FROM CTE
UNION ALL 
SELECT 'Totle',
    SUM(Austria_qty),
    SUM(Austria_totle),
    SUM(France_qty),
    SUM(France_totle),
    SUM(Germany_qty),
    SUM(Germany_totle),
    SUM(Italy_qty),
    SUM(Italy_totle) 
FROM CTE

sqlfiddle:http://sqlfiddle.com/#!18/90e75/32


如果您不想使用UNION ALL来组合两个查询。还有另一种方法可以做到。

使用CROSS APPLYValues

SELECT tt.brand,
       SUM(tt.austria_qty) 'austria_qty',
       SUM(tt.austria_totle) 'austria_totle',
       SUM(tt.france_qty) 'austria_qty',
       SUM(tt.france_totle) 'austria_totle',
       SUM(tt.germany_qty) 'austria_qty',
       SUM(tt.germany_totle) 'austria_totle',
       SUM(tt.italy_qty) 'austria_qty',
       SUM(tt.italy_totle) 'austria_totle'
FROM T CROSS APPLY (
  VALUES (Brand
          ,(CASE WHEN [Location] = 'Austria' THEN [qty] END) 
          ,(CASE WHEN [Location] = 'Austria' THEN [Price] END) 
          ,(CASE WHEN [Location] = 'France' THEN [qty] END) 
          ,(CASE WHEN [Location] = 'France' THEN [Price] END) 
          ,(CASE WHEN [Location] = 'Germany' THEN [qty] END) 
          ,(CASE WHEN [Location] = 'Germany' THEN [Price] END) 
          ,(CASE WHEN [Location] = 'Italy' THEN [qty] END)
          ,(CASE WHEN [Location] = 'Italy' THEN [Price] END) 
         ),
         (
         'Totle'
          ,(CASE WHEN [Location] = 'Austria' THEN [qty] END) 
          ,(CASE WHEN [Location] = 'Austria' THEN [Price] END) 
          ,(CASE WHEN [Location] = 'France' THEN [qty] END) 
          ,(CASE WHEN [Location] = 'France' THEN [Price] END) 
          ,(CASE WHEN [Location] = 'Germany' THEN [qty] END) 
          ,(CASE WHEN [Location] = 'Germany' THEN [Price] END) 
          ,(CASE WHEN [Location] = 'Italy' THEN [qty] END)
          ,(CASE WHEN [Location] = 'Italy' THEN [Price] END) 
         )
) tt(brand, 
     austria_qty, 
     austria_totle, 
     france_qty,  
     france_totle, 
     germany_qty, 
     germany_totle, 
     italy_qty, 
     italy_totle)
GROUP BY tt.brand

sqlfiddle:http://sqlfiddle.com/#!18/90e75/44

结果

|   Brand | Austria_qty |      Austria_totle | France_qty |       France_totle | Germany_qty | Germany_totle | Italy_qty |        Italy_totle |
|---------|-------------|--------------------|------------|--------------------|-------------|---------------|-----------|--------------------|
|   Apple |           1 |            1351.16 |          1 |               9.96 |           2 |       1583.85 |         1 |            1053.83 |
|  Huawei |           1 |             744.67 |     (null) |             (null) |           2 |     207704.86 |    (null) |             (null) |
|  Lenovo |           2 | 1184.2099999999998 |          2 |            1420.43 |           2 |       3454.91 |    (null) |             (null) |
|   Nokia |      (null) |             (null) |          1 |             796.03 |      (null) |        (null) |         1 |             538.41 |
| Samsung |      (null) |             (null) |          1 |            3327.14 |      (null) |        (null) |         1 |               9.09 |
|   Totle |           4 |            3280.04 |          5 | 5553.5599999999995 |           6 |     212743.62 |         3 | 1601.3299999999997 |