`

SQL 表数据旋转90度(二维转换)

 
阅读更多
/**//*
将表数据旋转90度(2007-11-19于海南三亚)

将下表数据:
A                    b           c           d           e           
-------------------- ----------- ----------- ----------- ----------- 
x                    1           2           3           4
y                    5           6           7           8
z                    9           10          11          12

转化成如下结果:
a                    x          y          z          
-------------------- ---------- ---------- ---------- 
b                    1          5          9
c                    2          6          10
d                    3          7          11
e                    4          8          12

*/

--生成测试数据
create table test1(A varchar(20),b int,c int,d int,e int)
insert into test1 select 'x',1,2 ,3 ,4
insert into test1 select 'y',5,6 ,7 ,8
insert into test1 select 'z',9,10,11,12
go

--生成中间数据表
declare @s varchar(8000)
set @s = 'create table test2(a varchar(20)'
select @s = @s + ',' + A + ' varchar(10)' from test1
set @s = @s + ')'
exec(@s)
print @s
--借助中间表实现行列转换
declare @name varchar(20)

declare t_cursor cursor for 
select name from syscolumns 
where id=object_id('test1') and colid > 1 order by colid

open t_cursor

fetch next from t_cursor into @name

while @@fetch_status = 0
begin
    exec('select ' + @name + ' as t into test3 from test1')
    set @s='insert into test2 select ''' + @name + ''''
    select @s = @s + ',''' + rtrim(t) + '''' from test3
    exec(@s)
    exec('drop table test3')
    fetch next from t_cursor into @name
end
close t_cursor
deallocate t_cursor

--查看行列互换处理结果
select * from test1
select * from test2

--删除表
drop table test1
drop table test2
----------------------------------------------------------------------------
/**//*固定的写法:*/
select t1.* , t2.y , t3.z from
(select a = 'b' , x = b from test1 where a = 'x') t1, 
(select a = 'b' , y = b from test1 where a = 'y') t2,
(select a = 'b' , z = b from test1 where a = 'z') t3
where t1.a = t2.a and t1.a = t2.a
union all
select t1.* , t2.y , t3.z from
(select a = 'c' , x = c from test1 where a = 'x') t1, 
(select a = 'c' , y = c from test1 where a = 'y') t2,
(select a = 'c' , z = c from test1 where a = 'z') t3
where t1.a = t2.a and t1.a = t2.a
union all
select t1.* , t2.y , t3.z from
(select a = 'd' , x = d from test1 where a = 'x') t1, 
(select a = 'd' , y = d from test1 where a = 'y') t2,
(select a = 'd' , z = d from test1 where a = 'z') t3
where t1.a = t2.a and t1.a = t2.a
union all
select t1.* , t2.y , t3.z from
(select a = 'e' , x = e from test1 where a = 'x') t1, 
(select a = 'e' , y = e from test1 where a = 'y') t2,
(select a = 'e' , z = e from test1 where a = 'z') t3
where t1.a = t2.a and t1.a = t2.a

----------------------------------------------------------------------------
/**//*
表tb,数据如下:
项目种类  业绩  提成
洗吹类  200   10
外卖      100   5
合计      300   15
转换成:
项目种类  洗吹类  外卖  合计
业绩      200     100   300
提成      10      5     15
*/

create table tb
(
  项目种类 varchar(10),
  业绩     int,
  提成     int
)

insert into tb(项目种类,业绩,提成) values('洗吹类',200,10)
insert into tb(项目种类,业绩,提成) values('外卖'  ,100,5)
insert into tb(项目种类,业绩,提成) values('合计'  ,300,15)
go

select 项目种类,sum(洗吹类) as 洗吹类 , sum(外卖) as 外卖 , sum(合计) as 合计 from
(
  select 项目种类 = '业绩',
         洗吹类   = case when 项目种类 = '洗吹类' then 业绩 else 0 end,
         外卖     = case when 项目种类 = '外卖'   then 业绩 else 0 end,
         合计     = case when 项目种类 = '合计'   then 业绩 else 0 end
  from tb
union all
  select 项目种类 = '提成' ,
         洗吹类   = case when 项目种类 = '洗吹类' then 提成 else 0 end,
         外卖     = case when 项目种类 = '外卖'   then 提成 else 0 end,
         合计     = case when 项目种类 = '合计'   then 提成 else 0 end
  from tb
) m
group by 项目种类
order by 项目种类 desc

drop table tb

/**//*
项目种类 洗吹类      外卖        合计          
-------- ----------- ----------- ----------- 
业绩     200         100         300
提成     10          5           15

(所影响的行数为 2 行)
*/

--------------------------------------------------------------------------
/**//*
数据库中tb表格如下
 
月份    工资   福利  奖金
月     100    200   300
月     110    210   310
月     120    220   320
月     130    230   330

我想得到的结果是

项目   1月    2月  3月  4月
工资   100    110  120  130
福利   200    210  220  230
奖金   300    310  320  330

就是说完全把表格的行列颠倒,有点像那种旋转矩阵,请问如何用sql 语句实现?
*/

if exists (select * from dbo.sysobjects
where id = object_id(N'[dbo].[p_zj]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[p_zj]
GO
/**//*--行列互换的通用存储过程(原著:邹建):将指定的表,按指定的字段进行行列互换*/

create proc p_zj
       @tbname sysname, --要处理的表名
       @fdname sysname, --做为转换的列名
       @new_fdname sysname='' --为转换后的列指定列名
as
declare @s1 varchar(8000) , @s2 varchar(8000),
        @s3 varchar(8000) , @s4 varchar(8000),
        @s5 varchar(8000) , @i varchar(10)
select @s1 = '' , @s2 = '' , @s3 = '' , @s4 = '' , @s5 = '' , @i = '0'
select @s1 = @s1 + ',@' + @i + ' varchar(8000)',
       @s2 = @s2 + ',@' + @i + '=''' + case isnull(@new_fdname , '') when '' then ''
       else @new_fdname + '=' end + '''''' + name + '''''''',
       @s3 = @s3 + 'select @' + @i + '=@' + @i + '+'',['' + [' + @fdname + 
       ']+'']=''+cast([' + name + '] as varchar) from [' + @tbname + ']',
       @s4 = @s4 + ',@' + @i + '=''select ''+@' + @i,
       @s5 = @s5 + '+'' union all ''+@' + @i,
       @i=cast(@i as int)+1
from syscolumns
where object_id(@tbname)=id and name<>@fdname

select @s1=substring(@s1,2,8000),
       @s2=substring(@s2,2,8000),
       @s4=substring(@s4,2,8000),
       @s5=substring(@s5,16,8000)
exec('declare ' + @s1 + 'select ' + @s2 + @s3 + 'select ' + @s4 + '
exec(' + @s5 + ')')
go

--用上面的存储过程测试:

create table Test(月份 varchar(4), 工资 int, 福利 int, 奖金 int)
insert Test 
select '1月',100,200,300 union all
select '2月',110,210,310 union all
select '3月',120,220,320 union all
select '4月',130,230,330
go

exec p_zj 'Test', '月份' , '项目'

drop table Test
drop proc p_zj

/**//*
项目   1月         2月         3月         4月          
---- ----------- ----------- ----------- ----------- 
福利   200         210         220         230
工资   100         110         120         130
奖金   300         310         320         330

(所影响的行数为 3 行)
*/

/**//*
静态写法(SQL2005)
*/
--测试环境
create table Test(月份 varchar(4), 工资 int, 福利 int, 奖金 int)
insert Test
select '1月',100,200,300 union all
select '2月',110,210,310 union all
select '3月',120,220,320 union all
select '4月',130,230,330
go
--测试语句
SELECT * FROM 
(
  SELECT 考核月份,月份,金额 FROM 
     (SELECT 月份, 工资, 福利, 奖金 FROM Test) p
  UNPIVOT
     (金额 FOR 考核月份 IN (工资, 福利, 奖金))AS unpvt
) T
PIVOT
(MAX(金额)  FOR 月份 in ([1月],[2月],[3月],[4月]))AS pt

--测试结果

/**//*
考核月份  1月     2月      3月     4月
-------  -----  -----   ------  -------
福利200210220230
工资100110120130
奖金300310320330
*/

--删除环境
Drop table Test
分享到:
评论

相关推荐

    空间数据的转换与处理

    地理坐标系统基于地球表面的经纬度表示,而投影坐标系统则是将三维地球表面上的经纬度通过数学转换为二维平面上的坐标系统。 - 当原始数据与某已知数据的投影相同,可以直接选择该数据的坐标系统作为参考。 通过...

    二十四、pandas数据分析

    该库的主要数据结构是 Series(一维数据)和 DataFrame(二维数据),这两种数据结构足以处理金融、统计、社会科学、工程等领域里的多数案例。 数据结构是 pandas 的基础,Series 用于处理一维数据,而 DataFrame ...

    复诊率分析模型的建立数据源 多维数据集 数据立方体

    这是数据分析的核心部分,它将原始的二维表格数据转换为多维结构,便于进行复杂的查询和分析。在VS2008中,我们选择“新建多维数据集”,并使用现有的表作为数据基础。这里,事实表通常是包含复诊率计算所需数值指标...

    基于SQL Server数据库平台的铀矿资源数据集成应用系统设计与开发.pdf

    8. 三维可视化:系统的三维可视化功能支持用户从不同角度对数据进行可视化操作,如XYZ三维坐标系显示、缩放、旋转等,以便用户更直观地理解和分析数据。 9. GIS开发与地质三维建模:文中还提到了GIS(地理信息系统...

    python 数据清洗之数据合并、转换、过滤、排序

    - 重塑:`reshape` 函数改变数据的维度,如将一维数组转换为二维 DataFrame。 - 轴向旋转:`unstack` 和 `stack` 分别将列转为行(宽表转长表)和行转为列(长表转宽表)。 6. 其他转换: - 缺失值处理:Pandas ...

    数据挖掘知识点概况及试题.pdf

    星型模式和雪花型模式是数据仓库中的数据组织形式,前者以事实表为中心,后者对维表进行规范化。数据仓库中的数据有多个综合级别,从细节到高度综合。 SQL Server SSAS在数据仓库中扮演着整合业务数据的角色,用于...

    Server数据仓库解决方案

    #### 二、Oracle数据仓库开发工具 Oracle提供的数据仓库解决方案以Oracle 9i为核心,涵盖了从数据建模到数据挖掘的全流程: - **Oracle Warehouse Builder**:用于构建数据仓库的架构,支持数据抽取、转移、装载、...

    数据仓库与数据挖掘实验二.doc

    OLAP的主要操作包括切片(选取数据集的一部分)、切块(选取多个维度的交叉部分)、旋转(改变数据透视表的视角)和钻取(从高层次细节到低层次细节的深入查看)。通过这些操作,用户可以迅速从不同视角深入分析数据...

    阿里巴巴2016算法工程师附加题

    2. **旋转操作**:定义旋转操作的具体实现,例如顺时针旋转90度可以通过行列转换和翻转来实现。 3. **命令解析**:根据输入的命令执行相应的旋转操作。 通过这样的问题,可以考察应聘者在解决实际问题时的逻辑思维...

    GIS论文 MapInfo和AutoCAD相互转换在城镇规划中的应用.pdf

    1. **强大的数字制图功能**:基于拓扑数据结构,可以高效地绘制二维或三维图形,非常适合于建筑设计和工程绘图。 2. **精确的绘图控制**:用户可以精确控制图纸上的每一处细节,包括线条宽度、曲线曲率等,这在...

    python当中的pandas库的学习报告

    DataFrame是二维表格型数据结构,包含列标签(columns)和行标签(index),可以看作是由多个Series组成的字典。 **2. 数据导入与导出** Pandas支持多种数据格式的读写,如CSV、JSON、SQL数据库、Excel文件和HDF5等...

    transform.rar

    3. **前端开发中的Transform**:CSS中的`transform`属性允许对元素进行二维或三维的几何变换,如平移(translate)、旋转(rotate)、缩放(scale)和倾斜(skew),这些变换不会影响到其他元素的位置,而是改变元素...

    fme 内置的函数功能介绍

    FME(Feature Manipulation Engine)是一款强大的数据转换软件,它能够处理各种格式的空间数据,并通过其内置的多种转换器(Transformer)来实现对数据的清洗、转换与分析等功能。本文将详细介绍FME中几个主要类别下...

    C#开发3D图形显示源码

    这可能涉及到创建数据库连接、执行SELECT语句获取空间数据,以及将3D模型的坐标转换为适应数据库的空间参考系。 综上所述,“C#开发3D图形显示源码”涵盖了一系列关键概念,包括3D渲染技术、材质与光照、3D旋转的...

    重塑矩阵:(旋转和反旋转)-matlab开发

    例如,如果你有一个一维数组并想将其转换为二维矩阵,或者相反,`reshape` 可以做到这一点。基本语法是 `B = reshape(A, m, n)`,其中 `A` 是原始矩阵,`m` 和 `n` 分别是新矩阵的行数和列数。 接着,我们讨论...

    FME使用说明-pdf

    FME(Feature Manipulation Engine)是一款功能强大的GIS数据转换工具,它能够帮助用户实现不同格式之间GIS数据的高效转换与处理。FME支持广泛的数据格式,并提供了丰富的工具集来满足复杂的转换需求。本文旨在为...

    2021-2022计算机二级等级考试试题及答案No.15909.docx

    19. 关系数据库:关系数据库系统管理的是多个二维表,每个二维表代表一个关系。 20. 字符常量:'\v'、'\x2a'和'a'都是字符常量,但"\0"是字符串常量,表示空字符。 21. SQL查询:查询类型为"食品"的商品信息并按...

    采用VC++与OpenGL的三维场景编辑系统的研究与设计

    4. **数据库集成**:通过SQL数据库存储和管理场景模型的数据,使得系统能够在不同的会话之间保持数据的一致性和完整性。 #### 四、结论与展望 本文介绍了一个基于VC++和OpenGL技术的三维场景编辑系统的构建、研究...

    java面试题及答案-非常全面(包括基础、网络、数据结构、算法及IT大厂面经)

    - **第二范式**:确保表中的每个非键列都完全依赖于主键。 - **第三范式**:消除传递依赖关系。 ### Nosql - **特点**:非关系型数据库,适合大数据和实时应用。 - **类型**:包括键值存储、文档数据库、图形...

    skyline

    - **Skyline**: 支持二维、三维数据及影像数据的导入、建模,操作便捷且灵活性高。 - **VRMap2.X**: 提供一般的影像漫游体验。 - **IMAGIS**: 不支持此功能。 - **GeoStar**: 支持性较差。 - **MapInfo**: 不支持此...

Global site tag (gtag.js) - Google Analytics