Oracle行列互换 横表和纵表

/*
在实际使用sql工作中总会碰到将某一列的值放到标题中显示.就是总说的行列转换或者互换.
比如有如下数据:
ID NAME       KECHENG              CHENGJI
-- ---------- -------------------- -------
1  a          语文                 80
2  a          数学                 70
3  b          语文                 40
4  b          数学                 100
5  c          语文                 90
6  c          数学                 92
那末我要求显示的结果是:
NAME       YUWEN                  SHUXUE
---------- ---------------------- ----------------------
a          80                     70
也就是说把课程这一列放到行上显示.把成绩按照课程分配到相对应的行.
我只介绍2中简单易用的方法,使用游标或者建立临时表的方法就不介绍了.效率很慢,不易理解.
首先建立表:
*/

create table fzq
(
id varchar(2),
name varchar(10),
kecheng varchar(20),
chengji varchar(3)
);

--插入数据:
insert into fzq values (‘1‘,‘a‘,‘语文‘,‘80‘);
insert into fzq values(‘2‘,‘a‘,‘shuxue‘,‘70‘);
insert into fzq values (‘3‘,‘b‘,‘yuwen‘,‘40‘);
insert into fzq values (‘4‘,‘b‘,‘shuxu‘,‘100‘);
insert into fzq values (‘5‘,‘c‘,‘yuwen‘,‘90‘);
insert into fzq values (‘6‘,‘c‘,‘shuxu‘,‘92‘);

/*首先使用union.如果课程这列有多个值,那么脚本的代码就很长了.*/

select name,sum(yuwen) yuwen,sum(shuxue) shuxue from
(
select name,chengji yuwen,‘0‘ shuxue from fzq
where kecheng=‘yuwen‘ union
select name,‘0‘ yuwen,chengji  shuxue
from fzq
where kecheng=‘shuxue‘
) aaa
group BY name;

/*执行结果:
NAME       YUWEN                  SHUXUE
---------- ---------------------- ----------------------
a          80                     70
b          40                     100
c          90                     92
*/
/*
其次是用case.这种方法代码比较短.适合列值很多的情况.
*/

select name, sum(case kecheng when ‘yuwen‘ then chengji end) yuwen,
             sum(case kecheng  when ‘shuxue‘ then chengji  end) shuxue
from fzq
group by name;

/*执行结果:
NAME       YUWEN                  SHUXUE
---------- ---------------------- ----------------------
a          80                     70
b          40                     100
c          90                     92
所有例子在oracle中测试,sql server没有测试,请根据实际情况修改

如果有更好的方法,欢迎交流.
*/

横表和纵表

第一张图就是横表,一行表示了一个实体记录,这就是我们传统的设计表的形式

第二张图就是纵表,他的一行记录,是用于表示某个学生的属性名和属性值对应关系,像这边有两个属性(名字和性别),在纵表中就要用两条记录来表示一个学生。

从上面可以观察出,横表的好处是清晰可见,一目了然,但是有一个弊端,如果现在要把这个表加一个字段,那么就必须重建表结构。对于这种情况,在纵表中只需要添加一条记录,就可以添加一个字段,所消耗的代价远比横表小,但是纵表的对于数据描述不是很清晰,而且会造成数据库数量很多,两者利弊在于此。所以,应该把不容易改动表结构的设计成横表,把容易经常改动不确定的表结构设计成纵表。

在实际开发中,经常需要互相转换横表和纵表的形式,这里贴个从纵表数据转成横表显示的形式。

纵表转横表

sql代码:

Select student_no,
        max(decode(field_name,‘student_name‘,field_value)) As student_name,
        max(decode(field_name,‘student_sex‘,field_value )) As student_sex
    From cuc_student_y Group By student_no;
时间: 2024-12-19 21:25:48

Oracle行列互换 横表和纵表的相关文章

SQL 查询横表变竖表

SQL 查询横表变竖表 /*普通行列转换 假设有张学生成绩表(tb)如下:Name Subject Result张三 语文 74张三 数学 83张三 物理 93李四 语文 74李四 数学 84李四 物理 94*/ -------------------------------------------------------------------------/*想变成 姓名         语文        数学        物理          ---------- ----------

Oracle 11g完全卸载方案(注册表清理)

1.如果数据库配置了自动存储管理(ASM),应该先删除聚集同步服务CSS(Cluster Synchronization Services). 删除CSS服务的方法是在DOS命令行中执行如下命令: localconfig delete 2.在"服务"窗口中停止oracle的所有服务. 3.在"开始"菜单中依次选择 "程序" / "Oracle-OraDb11g_home1" / "Oracle Installatio

Oracle基础(五):多表查询

一.多表查询 (一)简单多表查询 1.多表查询的机制 1)SQL: SELECT * FROM emp; --14条记录 SELECT * FROM dept;--4条记录 SELECT * FROM emp,dept;--显示56条数据??为什么 2)分析: 先从 dept 选择一条记录(deptno=10).分别于 emp中的14条记录分别匹配.显示14条记录. 再从 dept 选择一条记录(deptno=20),分别于 emp中的14条记录分别匹配.显示14条记录. 依次类推. water

Oracle Study之案例--异构平台传输表空间(Linux至AIX)

Oracle Study之案例--异构平台传输表空间(Linux至AIX) 系统架构: 可                   源    库               目标库 操作系统 Linux RH6    AIX 5.3-09 主机名 rh6(192.168.8.245) aix211(192.168.8.211) 数据版本 Oracle 11gR2 Oracle 11gR2 数据库名 prod orcl 表空间 test1 test1    可传输表空间概述 Oracle 的可传输表空

oracle创建表之前判断表是否存在,如果存在则删除已有表

Mysql 创建表之前判断表是否存在,如果存在则删除已有表 DROP TABLE IF EXISTS sys_area; CREATE TABLE sys_area ( id varchar(64) NOT NULL COMMENT '编号', parent_id varchar(64) NOT NULL COMMENT '父级编号', parent_ids varchar(2000) NOT NULL COMMENT '所有父级编号', name varchar(100) NOT NULL C

oracle 、sql server 、mysql 复制表数据

我们知道在oracle 中复制表数据的方式是使用 create table table_name as select * from table_name 而在sql server  中是不能这么使用的 语句如下: select * into table_name from table_name; 而在 mysql 中有两种方式 1. create table a like b 2. 类似oracle的方式 create table table_name as select * from tabl

Oracle学习(九):创建和管理表

1.知识点:可以对照下面的录屏进行阅读 SQL> --创建表 SQL> create table test1 2 (tid number, 3 tname varchar2(20), 4 hidatedate date default sysdate); SQL> --使用as和子查询快速建表 SQL> --创建表:包含员工号 姓名 月薪 年薪 部门名称 SQL> create table empincome 2 as 3 select empno,ename,sal,sal

Oracle中使用游标获取指定数据表的所有字段名对应的字符串

操作步骤:打开PLSQL Developer后,直接执行下面的语句就可以出来 --Oracle中使用游标获取指定数据表的所有字段名对应的字符串 declare mytablename VARCHAR(255):='STAFFDOC'; --定义要查询的数据表名变量,STAFFDOC为我测试用的数据表名,请修改成您的数据库中的对应数据表名字mystring NVARCHAR2(4000):=''; --定义要输出的字符串变量 cursor mycursor is --定义游标          s

SWAP_JOIN_INPUTS Oracle Hint(处理hash join强制大表(segment_size大)作为被驱动表)

swap_join_inputs是针对哈希连接的hint,它的含义是让优化器交换原哈希连接的驱动表和被驱动表的顺序,即在依然走哈希连接的情况下让原哈希连接的驱动表变被驱动表,让原哈希连接的被驱动表变为驱动表. 注意,在swap_join_inputs hint中指定的目标表应该是原哈希连接中的被驱动表,否则oracle会忽略该hint. /*+ swap_join_inputs(原哈希连接的被驱动表) */ 其使用范例如下: 1 2 select /*+ leading(dept) use_ha