如何在 SQL Server 2008 中将行切换到列,反之亦然
Posted
技术标签:
【中文标题】如何在 SQL Server 2008 中将行切换到列,反之亦然【英文标题】:How to switch rows to columns and vice versa in SQL Server 2008 【发布时间】:2016-09-01 05:44:23 【问题描述】:我在 SQL Server 2008 中无法将行切换到列,反之亦然,我尝试了对解决方案的任何查询,但没有得到正确的结果。
我有一张如下表:
声明@tmpTable 表 (名称 varchar(20)、date_date、sales_code char(1)、sales smallint、 Earn int) 插入@tmpTable 值(“罗伯特”、“2016/8/1”、“A”、2、30), ('罗伯特', '2016/8/1', 'B', 3, 45), ('罗伯特', '2016/8/2', 'B', 1, 15), ('罗伯特', '2016/8/3', 'B', 2, 30), ('Jhon', '2016/8/1', 'A', 3, 45), ('Jhon', '2016/8/2', 'A', 3, 45), ('Jhon', '2016/8/3', 'B', 2, 30) 从@tmpTable中选择*;结果:
姓名 date_sales_code 销售额 ------ ---------- ---------- ----- ------ 罗伯特 2016-08-01 A 2 30 罗伯特 2016-08-01 B 3 45 罗伯特 2016-08-02 B 1 15 罗伯特 2016-08-03 B 2 30 约翰 2016-08-01 A 3 45 约翰 2016-08-02 A 3 45 约翰 2016-08-03 B 2 30然后,我有下一个查询:
选择 * 从 ( 选择名称,'sales_code'作为类别,日期_,sales_code from 选择 * 从 ( 选择名称,日期_ ,STUFF((SELECT ', ' + sales_code [text()] 来自@tmpTable WHERE date_ = t.date_ FOR XML PATH(''), 类型) .value('.','NVARCHAR(MAX)'),1,2,' ') sales_code ,STUFF((SELECT ', ' + convert(varchar(max), sales) [text()] 来自@tmpTable WHERE date_ = t.date_ FOR XML PATH(''), 类型) .value('.','NVARCHAR(MAX)'),1,2,' ') 销售额 ,STUFF((SELECT ', ' + 转换(varchar(max), 获得) [text()] 来自@tmpTable WHERE date_ = t.date_ FOR XML PATH(''), 类型) .value('.','NVARCHAR(MAX)'),1,2,' ') 获得 来自@tmpTable t 按名称分组,日期_ ) 作为一个 ) 作为一个 ) 作为一个 枢轴 ( max(sales_code) FOR date_ IN ([2016/8/1], [2016/8/2], [2016/8/3]) ) 作为光伏 联合所有 选择 * 从 ( 选择名称,“销售额”作为类别,日期_,销售额来自( 选择 * 从 ( 选择名称,日期_ ,STUFF((SELECT ', ' + sales_code [text()] 来自@tmpTable WHERE date_ = t.date_ FOR XML PATH(''), 类型) .value('.','NVARCHAR(MAX)'),1,2,' ') sales_code ,STUFF((SELECT ', ' + convert(varchar(max), sales) [text()] 来自@tmpTable WHERE date_ = t.date_ FOR XML PATH(''), 类型) .value('.','NVARCHAR(MAX)'),1,2,' ') 销售额 ,STUFF((SELECT ', ' + 转换(varchar(max), 获得) [text()] 来自@tmpTable WHERE date_ = t.date_ FOR XML PATH(''), 类型) .value('.','NVARCHAR(MAX)'),1,2,' ') 获得 来自@tmpTable t 按名称分组,日期_ ) 作为一个 ) 作为一个 ) 作为一个 枢轴 ( max(sales) FOR date_ IN ([2016/8/1], [2016/8/2], [2016/8/3]) ) 作为光伏 联合所有 选择 * 从 ( 选择名称,'earned'作为类别,date_,从( 选择 * 从 ( 选择名称,日期_ ,STUFF((SELECT ', ' + sales_code [text()] 来自@tmpTable WHERE date_ = t.date_ FOR XML PATH(''), 类型) .value('.','NVARCHAR(MAX)'),1,2,' ') sales_code ,STUFF((SELECT ', ' + convert(varchar(max), sales) [text()] 来自@tmpTable WHERE date_ = t.date_ FOR XML PATH(''), 类型) .value('.','NVARCHAR(MAX)'),1,2,' ') 销售额 ,STUFF((SELECT ', ' + 转换(varchar(max), 获得) [text()] 来自@tmpTable WHERE date_ = t.date_ FOR XML PATH(''), 类型) .value('.','NVARCHAR(MAX)'),1,2,' ') 获得 来自@tmpTable t 按名称分组,日期_ ) 作为一个 ) 作为一个 ) 作为一个 枢轴 ( max(earned) FOR date_ IN ([2016/8/1], [2016/8/2], [2016/8/3]) ) 作为光伏它会显示结果:
名称类别 2016/8/1 2016/8/2 2016/8/3 -------- -------- -------- -------- -------- Jhon 销售代码 A、B、A B、A B、B Robert sales_code A、B、A B、A B、B Jhon 销售 2, 3, 3 1, 3 2, 2 罗伯特销售 2, 3, 3 1, 3 2, 2 Jhon 获得 30, 45, 45 15, 45 30, 30 罗伯特赚了 30, 45, 45 15, 45 30, 30但是,我想得到以下结果:
名称类别 2016/8/1 2016/8/2 2016/8/3 ---- -------- -------- -------- -------- Robert sales_code A, B B B 罗伯特销售 2, 3 1 2 罗伯特赚了 30, 45 15 30 Jhon sales_code A A B 约翰销售 3 3 2 约翰赚了 45 45 30非常感谢您的帮助。
【问题讨论】:
Stack Overflow 不是免费的代码编写服务,请展示您的代码/努力以及实际问题所在。 @ChrisPickford,我已经更新了我的问题,抱歉我是 Stack Overflow 的新手。 【参考方案1】:首先您需要对数据进行反透视。为此,所有数据类型都非常匹配,因此您需要将 2 个数字列转换为 varchars。
在 unpivot 之前仍然使用东西来获取每个名称 date_ 的组合值,但使用 distinct 只获取名称 date_ 值一次。
在你取消旋转后,你只需要再次旋转。
SELECT *
FROM ( SELECT DISTINCT
Name,
date_,
sales_code = STUFF((SELECT ', ' + sales_code
FROM @tmpTable t2
WHERE t2.Name = t.Name AND t2.date_ = t.date_
FOR XML PATH('')), 1, 2, ''),
sales = STUFF((SELECT ', ' + CONVERT(VARCHAR, sales)
FROM @tmpTable t2
WHERE t2.Name = t.Name AND t2.date_ = t.date_
FOR XML PATH('')), 1, 2, ''),
earned = STUFF((SELECT ', ' + CONVERT(VARCHAR, earned)
FROM @tmpTable t2
WHERE t2.Name = t.Name AND t2.date_ = t.date_
FOR XML PATH('')), 1, 2, '')
FROM @tmpTable t) t
UNPIVOT (
val
FOR category IN (sales_code, sales, earned)
) up
PIVOT (
MAX(val)
FOR date_ IN ([2016-08-01], [2016-08-02], [2016-08-03])
) p
ORDER BY name DESC,
category DESC
【讨论】:
非常感谢你拯救了我的一天。以上是关于如何在 SQL Server 2008 中将行切换到列,反之亦然的主要内容,如果未能解决你的问题,请参考以下文章
如何在 sql server 2008 中将日期与 GETDATE() 进行比较
如何在 Sql Server 2008 R2 中将列转换为行?
我们如何在 C# 中将访问数据库(.mdb)导入 sql server 2008