SQL Server:在具有两列的表上进行无聚合的旋转
Posted
技术标签:
【中文标题】SQL Server:在具有两列的表上进行无聚合的旋转【英文标题】:SQL Server: pivoting without aggregation on a table with two columns 【发布时间】:2018-03-13 03:37:53 【问题描述】:这是一道测试题。我有一个有两列的表。我想以其中一个为中心并输出另一个。
表结构:
(Name varchar(10), Age int)
我需要将年龄值作为列的输出,并在每个年龄值下方列出名称。
通过搜索,我只看到至少有一个其他列用于“分组依据”的示例,因为需要更好的术语。换句话说,输出的每一行都有一个公因子。我的问题没有这个属性。
我试过了:
SELECT
[agevalue1], [agevalue2], [agevalue3], [agevalue4]
FROM
(SELECT Name, Age FROM MyClass) AS SourceTable
PIVOT
(MAX(Name)
FOR Age IN ([agevalue1], [agevalue2], [agevalue3], [agevalue4])
) AS PivotTable;
我将 agevalue* 指定为字符串,即用引号引起来。我的列标题没问题,但在它们下面有一排 NULLS。
P.S.:解决方案不需要使用 pivot 但我想不出替代方法。
样本数据:
Name Age
Bob 11
Rick 25
Nina 30
Sam 11
Cora 16
Rachel 25
期望的输出:
11 16 25 30
Bob Cora Rick Nina
Sam NULL Rachel NULL
【问题讨论】:
【参考方案1】:试试这个:
with tab as
(
Select 'A' Name, 10 Age union all
Select 'B',11 union all
Select 'c',10 union all
Select 'D',11 union all
Select 'E',11 union all
Select 'F',11
)
select distinct
Age
, stuff((
select ',' + g.Name
from tab g
where g.age = g1.age
order by g.age
for xml path('')
),1,1,'') as Names_With_Same_Age
from tab g1
group by g1.age,Name
【讨论】:
这导致输出水平打印,如:10 A,c 11 B,D,E,F【参考方案2】:将这些组合成一行:
11 16 25 30
Bob Cora Rick Nina
并将它们与另一组分开,例如:
11 16 25 30
Sam NULL Rachel NULL
他们必须在每一行之间有一些不同的东西,因为执行MAX(Name)
只会为每个年龄获得一个名称。
此查询创建一个将特定Age
链接到行号的数字,然后旋转结果。正如您所说,PIVOT
将按 PIVOT
函数中未引用的所有列进行分组,因此它将按此行索引器分组,按照您的需要分隔值。
;WITH IndexedClass AS
(
SELECT
M.Name,
M.Age,
-- The ordering will determine which person goes first for each Age
RowIndexer = ROW_NUMBER() OVER (PARTITION BY M.Age ORDER BY M.Name)
FROM
MyClass AS M
)
SELECT
P.[11],
P.[16],
P.[25],
P.[30]
FROM
IndexedClass AS I
PIVOT (
MAX(I.Name) FOR I.Age IN ([11], [16], [25], [30])
) AS P
【讨论】:
以上是关于SQL Server:在具有两列的表上进行无聚合的旋转的主要内容,如果未能解决你的问题,请参考以下文章
在 SQL Server 2014 中使用聚集列存储索引时,具有大量列的表是不是仍然是反模式?