SQL将行移动为列 - PIVOT查询

时间:2017-08-13 06:12:45

标签: sql sql-server

假设:

+-----------+---------------+-------------+-------+
|   Name    |   Location    | Description | Value |
+-----------+---------------+-------------+-------+
| Company A | Houston       | Sales       |   100 |
| Company A | Houston       | Profit      |    50 |
| Company B | San Francisco | Sales       |   500 |
| Company B | San Francisco | Profit      |   200 |
| Company C | New York      | Sales       |   200 |
| Company C | San Francisco | Profit      |   150 |
+-----------+---------------+-------------+-------+

如何使用SQL将其转换为:

+----------+---------------+--------+---------+
|   Name   |   Location    | Sales  | Profit  |
+----------+---------------+--------+---------+
| CompanyA | Houston       |    100 |      50 |
| CompanyB | San Francisco |    500 |     200 |
| CompanyC | New York      |    200 |     150 |
+----------+---------------+--------+---------+

4 个答案:

答案 0 :(得分:3)

尝试1或2个查询:http://sqlfiddle.com/#!6/bb33b/7
第二个给出了你问题中显示的确切结果,但我的猜测是第一个是你正在寻找的。

SELECT Name, Location,
       Sum( Case Description when 'Sales' Then Value else 0 end ) Sales,
       Sum( Case Description when 'Profit' Then Value else 0 end ) Profit
FROM table1
GROUP BY Name, Location
Order by 1,2
;

|      Name |      Location | Sales | Profit |
|-----------|---------------|-------|--------|
| Company A |       Houston |   100 |     50 |
| Company B | San Francisco |   500 |    200 |
| Company C |      New York |   200 |      0 |
| Company C | San Francisco |     0 |    150 |
SELECT Name, Min( Location ) As Location,
       Sum( Case Description when 'Sales' Then Value else 0 end ) Sales,
       Sum( Case Description when 'Profit' Then Value else 0 end ) Profit
FROM table1
GROUP BY Name
Order by 1,2
;
;

|      Name |      Location | Sales | Profit |
|-----------|---------------|-------|--------|
| Company A |       Houston |   100 |     50 |
| Company B | San Francisco |   500 |    200 |
| Company C |      New York |   200 |    150 |

答案 1 :(得分:0)

假设您的描述值仅为SalesProfit,则此处为CTE解决方案。我打电话给初始表Before

with cteSales as (select name, value from Before where description = 'Sales')
, cteProfit as (select name, value from Before where description  = 'Profit')
select 
distinct 
    name
    , location
    , (select value from cteSales where name = B.name) as Sales
    , (select value from cteProfit where name = B.name) as Profit
from Before B

答案 2 :(得分:0)

要将数据转换为所需的表单,您可以执行以下操作:

 SELECT NAME
          ,LOCATION
          ,SUM (CASE WHEN DESCRIPTION = 'Sales' THEN Values ELSE 0 END) AS SALES
          ,SUM (CASE WHEN DESCRIPTION = 'Profit' THEN Values ELSE 0 END) AS PROFIT
 FROM yourtable
 GROUP BY NAME
               ,LOCATION

答案 3 :(得分:0)

您可以使用 PIVOT 函数将行值转换为列,但它会提供稍微不同但更合理的输出 -

 int x = 0;
switch (x) {
case 1:
    System.out.print(1);
case 0:
    System.out.print(1);
case 2:
    System.out.print(3);
}

将生成以下输出 -

SELECT Name, Location, Sales, Profit
FROM
(
    SELECT *
    FROM Table1
) AS SourceTable
PIVOT
(
  MIN(value)
  FOR Description IN (Sales, Profit)
) AS PivotTable
ORDER BY Name, Location;

您可以将此作为替代解决方案。