Oracle中的行转列例子详解
--场景1:
A B
a 1
a 2
a 3
b 4
b 5 希望实现如下效果:
a 1,2,3
b 4,5 create table tmp as
select 'a' A, 1 B from dual union all
select 'a' A, 2 B from dual union all
select 'a' A, 3 B from dual union all
select 'b' A, 4 B from dual union all
select 'b' A, 5 B from dual; 1.方法1:listagg
--listagg() + group by: 推荐使用
select a,listagg(b,',') within group (order by b) as c from tmp group by a;
--listagg() + over(partition by )
select distinct a,listagg(b,',') within group (order by b) over(partition by a) as c from tmp ; 2.wm_concat
select a,to_char(wm_concat(b)) as b from tmp group by a 3.sys_connect_by_path
select a, max(substr(sys_connect_by_path(b, ','), 2)) str
from (select a, b, row_number() over(partition by a order by b) rn from tmp)
start with rn = 1
connect by rn = prior rn + 1
and a = prior a
group by a; 4.max+decode
select a,
max(decode(rn, 1, b, null)) ||
max(decode(rn, 2, ',' || b, null)) ||
max(decode(rn, 3, ',' || b, null)) str
from (select a,b,row_number() over(partition by a order by b) as rn from tmp)
group by a
order by 1; 5.row_number()+lead
select a, str b
from (select a,
row_number() over(partition by a order by b) as rn,
b || lead(',' || b, 1) over(partition by a order by b) ||
lead(',' || b, 2) over(partition by a order by b) ||
lead(',' || b, 3) over(partition by a order by b) as str
from tmp
)
where rn = 1
order by 1; 6.model语句
select a, substr(str,2) b
from tmp
model return updated rows partition by(a) dimension by(row_number() over(partition by a order by b) as rn)
measures(cast(b as varchar2(20)) as str)
rules upsert iterate(3) until(presentv(str[iteration_number+2],1,0) = 0)
(str[] = str[]||','||str[iteration_number + 1])
order by 1; --场景2:
no sex
004 2
002 2
002 2
003 1
002 1 希望实现如下效果:
c1 c2
002 1 2
003 1 0
004 0 1 也就是说按no sex两个字段count人数,得到二维表。 --1.添加测试数据
create table tt(no varchar(20 char), sex number);
insert into tt values('',2);
insert into tt values('',2);
insert into tt values('',2);
insert into tt values('',1);
insert into tt values('',1);
commit;
select * from tt; --2.SQL实现
--存储过程动态拼接
--(1)使用case
create or replace procedure row_to_line
is
str_sql varchar2(4000);
begin
str_sql := ' create or replace view v_row_to_line as select no '; for x in (select distinct sex from tt) loop
str_sql := str_sql || ',count(case when sex = '||x.sex||' then 1 else null end ) "'||x.sex||'"';
end loop; str_sql := str_sql || ' from tt group by no order by no '; execute immediate str_sql; end;
/ --(2)使用decode
create or replace procedure row_to_line
is
str_sql varchar2(4000);
begin
str_sql := ' create or replace view v_row_to_line as select no '; for x in (select distinct sex from tt) loop
str_sql := str_sql || ',count(decode(sex, '||x.sex||', 1 , null)) "'||x.sex||'"';
end loop; str_sql := str_sql || ' from tt group by no order by no '; execute immediate str_sql; end;
/ SQL> exec row_to_line; PL/SQL procedure successfully completed SQL> select * from v_row_to_line; NO 1 2
---------------------------------------- ---------- ----------
002 1 2
003 1 0
004 0 1 --(3)动态传表名+列名
create or replace procedure row_to_line
(
str_tabname in varchar2,
str_col1 in varchar2,
i_col2 in varchar2
)
is
str_sql varchar2(4000);
begin
str_sql := ' create or replace view v_row_to_line as select '||str_col1||' '; for x in (select distinct sex from tt ) loop
str_sql := str_sql || ',count(decode('||i_col2||', '||x.sex||', 1, null)) "'||x.sex||'"';
end loop; str_sql := str_sql || ' from '||str_tabname||' group by '||str_col1||' order by '||str_col1||' '; execute immediate str_sql; end; --(4)使用游标
create or replace procedure row_to_line
(
str_tabname in varchar2,
str_col1 in varchar2,
i_col2 in varchar2,
cur_result out sys_refcursor
)
is
str_sql varchar2(4000);
begin
str_sql := 'select '||str_col1||' '; for x in (select distinct sex from tt ) loop
str_sql := str_sql || ',count(decode('||i_col2||', '||x.sex||', 1, null)) "'||x.sex||'"';
end loop; str_sql := str_sql || ' from '||str_tabname||' group by '||str_col1||' order by '||str_col1||' '; open cur_result for str_sql; end; --(5).使用sql语句也可以解决
select no,
count(case sex when 1 then 1 else null end) c1,
count(case sex when 2 then 1 else null end) c2
from tt
group by no
order by no;
Oracle中的行转列例子详解的更多相关文章
- oracle中的行转列,列转行
行转列:源表: 方法1:case when select y,sum(case when q=1 then amt end) q1,sum(case when q=2 then amt end) q2 ...
- oracle中的exists 和 in 用法详解
以前一直不知道exists和in的用法与效率,这次的项目中需要用到,所以自己研究了一下.下面是我举两个例子说明两者之间的效率问题. 前言概述: “exists”和“in”的效率问题,涉及到效率问题也就 ...
- oracle中,行转列函数wm_concat()结果有长度限制,重写该函数解决
--Type CREATE OR REPLACE TYPE zh_concat_im AUTHID CURRENT_USER AS OBJECT ( CURR_STR clob, STATIC FUN ...
- c语言中命令行参数argc,argv[]详解
main(int argc,char *argv[ ]) 1.argc为整数 2.argv为指针的指针(可理解为:char **argv or: char *argv[] or: char argv[ ...
- mysql 中实现行变列
前言: mysql行列变化,最难的就是将多个列变成多行,使用的比较多的是统计学中行变列,列变行,没有找到现成的函数或者语句,所以自己写了存储过程,使用动态sql来实现,应用业务场景,用户每个月都有使用 ...
- sql中的行转列和列转行的问题
sql中的行转列和列转行的问题 这是一个常见的问题,也是一个考的问题 1.行转列的问题 简单实例 CREATE TABLE #T ( MON1 INT, MON2 INT, MON3 INT ) G ...
- Delphi中TStringList类常用属性方法详解
TStrings是一个抽象类,在实际开发中,是除了基本类型外,应用得最多的. 常规的用法大家都知道,现在来讨论它的一些高级的用法. 先把要讨论的几个属性列出来: 1.CommaText 2.Delim ...
- Java中的equals和hashCode方法详解
Java中的equals和hashCode方法详解 转自 https://www.cnblogs.com/crazylqy/category/655181.html 参考:http://blog.c ...
- 转:Java中的equals和hashCode方法详解
转自:Java中的equals和hashCode方法详解 Java中的equals方法和hashCode方法是Object中的,所以每个对象都是有这两个方法的,有时候我们需要实现特定需求,可能要重写这 ...
随机推荐
- python 正则详解
正则表达式概述 正则表达式,又称正规表示式.正规表示法.正规表达式.规则表达式.常规表示法(英语:Regular Expression,在代码中常简写为regex.regexp或RE),是计算机科学的 ...
- 蛋疼zipline安装
比安装zipline更让人蛋疼的是,网上的教程没有一个是TM对的,真的是忍不住要吐血. 真的是一步一坑,一步一坑 安装环境: Windows7旗舰版,64位系统 python 版本3.5.3 我没有用 ...
- SpringMVC(八):使用Servlet原生API作为Spring MVC hanlder方法的参数
在SpringMVC开发中,是有场景需要在Handler方法中直接使用ServletAPI. 在Spring MVC Handler的方法中都支持哪些Servlet API作为参数呢? --Respo ...
- 常见web安全隐患及解决方案
Abstract 有关于WEB服务以及web应用的一些安全隐患总结资料. 1. 常见web安全隐患 1.1. 完全信赖用户提交内容 开发人员决不能相信一个来自外部的数据.不管它来自用户提交 ...
- 如何设计一款APP,才能吸引用户眼球
有APP分析机构研究表明,人们每天耗费在手机和平板上的平均时长为158分钟,其中127分钟是耗费在各类APP中,而仅有31分钟是花费在浏览网页上.随着人们对互联网的依赖性越来越强,移动APP发展迅速已 ...
- springboot全局异常处理
@Slf4j@ControllerAdvicepublic class RestExceptionHandler extends ResponseEntityExceptionHandler { @E ...
- java制作验证码(java验证码小程序)
手动制作java的验证码 Web应用验证码的组成: (1)输入框 (2)显示验证码的图片 验证码的制作流程: 生成验证码的容器使用 j2ee的servlet 生成图片需要的类: (1) Buffere ...
- JS 变量类型互相转换
转载自:http://zhaizhiyuan.blog.163.com/blog/static/1897672632009093147268/ Java中几种常用的数据类型之间转换方法: 1. sh ...
- Centos常用命令之:文件与目录管理
在centos中常用的文件与目录操作命令有: ◇chmod:修改文件或目录的权限 ◇mkdir:新建目录◇rmdir:删除目录◇rm:删除目录或文件◇cp:复制目录或文件◇mv:移动目录或文件 下面就 ...
- [测试题]wows
Description 山山最近在玩一款游戏叫战舰世界(steam 游戏太少了),他被大舰巨炮的魅力折服,于是山山开了一局游戏,这次发现目标是一艘战列舰新墨西哥级,舰桥很高,原本应该打在目标身后的圆形 ...