Pivot/Transpose 行存储的电话号码

Pivot/Transpose telephone numbers stored in rows

我看过很多关于枢轴和转置数据的帖子和主题,我要么不理解它们(可能),要么我试图使我需要做的事情过于复杂。

我是 运行 一个简单的 select 语句,像这样:

SELECT Customer, Telephone
FROM DetailsTable
WHERE Customer = 74270571
GROUP BY Customer, Telephone

这个returns:

Customer | Telephone
74270571 | 01556589962
74270571 | 07756563729

而我想要得到的是

Customer | Tel1         | Tel2
74270571 | 01556589962  | 07756563729

最多可以有 5 个电话号码。

由于每个 Customer 有多个 Telephone 值,获得结果的最简单方法是使用像 row_number 这样的窗口函数为每个创建一个唯一值Telephone/Customer 组合。获得此值后,您可以 PIVOT 使用聚合函数和 CASE 表达式或 PIVOT 函数得到结果。

最多有五个电话号码,这使得将查询编写为硬编码或静态版本变得容易。使用带有 CASE 表达式的聚合函数,代码将是:

select 
  customer,
  Tel1 = max(case when rn = 1 then telephone else null end),
  Tel2 = max(case when rn = 2 then telephone else null end),
  Tel3 = max(case when rn = 3 then telephone else null end),
  Tel4 = max(case when rn = 4 then telephone else null end),
  Tel5 = max(case when rn = 5 then telephone else null end)
from
(
  select customer, telephone,
   rn = row_number() over(partition by customer order by telephone)
  from DetailsTable
) x
group by customer;

SQL Fiddle with Demo

如果您想使用 PIVOT 函数,则代码为:

select customer,
  Tel1,
  Tel2,
  Tel3, 
  Tel4, 
  Tel4
from
(
  select customer, telephone,
   col = 'Tel'+cast(row_number() over(partition by customer order by telephone)
                    as varchar(1))
  from DetailsTable
) x
pivot
(
  max(telephone)
  for col in (Tel1, Tel2, Tel3, Tel4, Tel5)
) p

参见 SQL Fiddle with Demo。两者都给出一个结果:

| CUSTOMER |       TEL1 |       TEL2 |   TEL3 |   TEL4 |
|----------|------------|------------|--------|--------|
| 74270571 | 1556589962 | 7756563729 | (null) | (null) |