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中的,所以每个对象都是有这两个方法的,有时候我们需要实现特定需求,可能要重写这 ...
随机推荐
- linux环境 安装chromedriver 和 phantomjs的方法
1 首先要下载浏览器驱动: 常用的是chromedriver 和phantomjs chromedirver下载地址: https://npm.taobao.org/mirrors/chromedri ...
- Java并发编程:synchronized和锁优化
1. 使用方法 synchronized 是 java 中最常用的保证线程安全的方式,synchronized 的作用主要有三方面: 确保线程互斥的访问代码块,同一时刻只有一个方法可以进入到临界区 保 ...
- JavaScript 重点笔记
JavaScript 重点笔记 ## 数组 // 必须掌握 - arr.length:获取数组元素的长度 - arr.splice(起始位置,长度):从数组中添加或删除元素. - arr.indexO ...
- 文本处理三剑客之grep
grep grep(支持基本正则表达式),egrep(支持扩展的正则表达式),fgrep(快速的grep,不支持正则表达式) grep是一个最初用于Unix操作系统的命令行工具.在给出文件列表或标准输 ...
- Windows10下的docker安装与入门 (二)使用docker引擎在容器中运行镜像
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化.容器是完全使用沙箱机制,相互之间不会有任何 ...
- Android:CheckBox控件
1)ChexkBox继承自CompoundButton组件: 2)isChecked()--确定是否选中:setChecked(bool checked)--设置选中或取消选中: 3)监听事件:Com ...
- 俄罗斯方块(2D、3D)
声明:这篇文章主要是参考几个别人的博文及源代码学习.参考文章: 1)http://blog.csdn.net/qian_f/article/details/19758671 2)http://yaca ...
- HTTP首部扫盲
[TOC] 之前在做web开发时使用到HTTP首部的时候遇到不熟悉的都是现用现查,时间一长印象就不深刻了.最近在重读<图解HTTP>,其中有一章是专门讲解HTTP首部的,讲解的HTTP首部 ...
- 在MySQL中使用子查询
子查询作为数据源 子查询生成的结果集包含行.列数据,因而非常适合将它与表一起包含在from子句的子查询里.例: SELECT d.dept_id, d.name, e_cnt.how_many num ...
- [LeetCode] Baseball Game 棒球游戏
You're now a baseball game point recorder. Given a list of strings, each string can be one of the 4 ...