`
lovejuan1314
  • 浏览: 342042 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Oracle 多行合并一行 方法

阅读更多
NOTE:特别声明一下内容转自网络
http://www.ningoo.net/html/2008/how_to_do_string_aggregate_on_oracle.html

假如有如下表,其中各个i值对应的行数是不定的
SQL> select * from t;

         I A          D
---------- ---------- -------------------
         1 b          2008-03-27 10:55:42
         1 a          2008-03-27 10:55:46
         1 d          2008-03-27 10:55:30
         2 z          2008-03-27 10:55:55
         2 t          2008-03-27 10:55:59

--- 要获得如下结果,注意字符串需要按照D列的时间排序:

1  d,b,a
2  z,t


这是一个比较典型的行列转换,有好几种实现方法

1.自定义函数实现

create or replace function my_concat(n number)
return varchar2
is
 type typ_cursor is ref cursor;
 v_cursor typ_cursor;
 v_temp varchar2(10);
 v_result varchar2(4000):= '';
 v_sql varchar2(200);
begin
 v_sql := 'select a from t where i=' || n ||' order by d';
 open v_cursor for v_sql;
 loop
    fetch v_cursor into v_temp;
    exit when v_cursor%notfound;
    v_result := v_result ||',' || v_temp;
 end loop;
 return substr(v_result,2);
end;

SQL> select i,my_concat(i) from t group by i;

         I MY_CONCAT(I)
---------- --------------------
         1 d,b,a
         2 z,t


虽然这种方式可以实现需求,但是如果表t的数据量很大,i的值又很多的情况下,因为针对每个i值都要执行一句select,扫描和排序的次数和i的值成正比,性能会非常差。

2.使用sys_connect_by_path

select i,ltrim(max(sys_connect_by_path(a,',')),',') a
from
(
select i,a,d,min(d) over(partition by i) d_min,
(row_number() over(order by i,d))+(dense_rank() over (order by i)) numid
from t
)
start with d=d_min connect by numid-1=prior numid
group by i;

从执行计划上来看,这种方式只需要扫描两次表,比自定义函数的方法,效率要高很多,尤其是表中数据量较大的时候:

3.使用wm_sys.wm_concat
这个函数也可以实现类似的行列转换需求,但是似乎没有办法做到直接根据另外一列排序,所以需要先通过子查询或者临时表排好序:
SQL> select i,wmsys.wm_concat(a) from t group by i;

         I WMSYS.WM_CONCAT(A)
---------- --------------------
         1 b,a,d
         2 z,t

SQL> select i,wmsys.wm_concat(a)
  2  from
  3  (select * from t order by i,d)
  4  group by i;

         I WMSYS.WM_CONCAT(A)
---------- --------------------
         1 d,b,a
         2 z,t

执行计划上看,只需要做一次表扫描就可以了,但是这个函数是加密过的,执行计划并不能显示函数内部的操作。


其他一些方法:
http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:2196162600402
http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:15637744429336
分享到:
评论
2 楼 lovebegar 2015-09-22  
很有价值,之前自己写都是第一种,学习了~
1 楼 li_hy2002 2012-08-27  
谢谢博主,项目里正好用到

相关推荐

    oracle多行合并一行

    ### Oracle多行合并为一行的方法 在Oracle数据库中,有时候我们需要将多行数据合并成一行进行展示或处理,尤其是在报表生成、数据展示等场景中。本文将详细介绍如何使用Oracle纯SQL语句实现这一功能,并通过具体...

    sql实现多行合并一行

    总结来说,通过巧妙地运用Oracle的`CONNECT BY`和`SYS_CONNECT_BY_PATH`函数,我们可以实现多行数据到一行的合并,这对于报告展示和数据分析非常实用。不过要注意的是,这种方法在大数据量下可能会有性能问题,因为...

    oracle10g,9i多行合并一行函数

    在Oracle 9i中,由于`wm_concat()`函数尚未被引入,因此需要采用更复杂的方法来实现多行合并为一行的功能。这里介绍一种使用`sys_connect_by_path()`函数结合`connect by`语法的方法。 **示例代码:** ```sql ...

    Oracle多行记录合并

    在Oracle数据库中,多行记录的合并通常是为了将相同字段的多行数据整合成一行,以便于数据分析或者简化展示。这种操作在报表制作、数据整理等场景中非常常见。本篇文章将详细介绍Oracle中实现多行记录合并的几种方法...

    oracle实现多行合并的方法

    本文实例讲述了oracle实现多行合并的方法。分享给大家供大家参考。具体分析如下: 在写sql时,经常会有将某列的字段合并起来,比如将某人名下每个月的工资列示,但是每个人只能占一行。 像这种场景,可能用行列转换...

    一列分割成多列,多行合并为一行

    SQL语句用with将列分割成多列存为临时表,再将多行某个字段拼接合并为一行

    Oracle 多行记录合并/连接/聚合字符串的几种方法

    这个问题涉及到字符串的连接和聚合,使得多个记录的某个字段值能够整合到一行。在Oracle中,虽然没有内置的聚合函数直接支持这种操作,但可以通过一些技巧和自定义方法来实现。下面我们将对几种常用的方法进行详细...

    Oracle字段转字符串/多行记录合并/连接/聚合字符串的几种方法

    在Oracle数据库中,有时我们需要将多个字段值转换为单个字符串,或者将多行记录合并成一行,这在数据处理和报告生成时尤其常见。Oracle提供了多种方法来实现这一目标,包括使用内置函数、PL/SQL过程以及一些高级特性...

    oracle某个字段多行记录转化为一行

    为了实现将Oracle数据库中某个字段的多行记录合并成一行记录的目标,可以采用编写自定义函数的方法。下面详细介绍该方法的具体步骤: #### 创建函数 `f_m_t` 首先,创建一个名为`f_m_t`的函数,该函数接受一个参数...

    Oracle多行记录字符串综合操作几种方法

    ### Oracle多行记录字符串综合操作几种方法 #### 引言 在Oracle数据库中,处理多行记录中的字符串是一项常见的需求,特别是在需要将多个值合并成一个字符串时。本文旨在介绍几种常用的多行记录字符串综合操作方法,...

    oracle将以逗号分隔字符串转多行

    在Oracle数据库中,将逗号分隔的字符串转换为多行是常见的数据处理需求,尤其在需要对每个分隔项进行单独操作时。这个过程通常涉及到字符串处理函数,如`REGEXP_SUBSTR`和`REPLACE`,以及层次查询结构`CONNECT BY`。...

    PLSQL单行函数和组函数详解

    在Oracle的PL/SQL编程中,函数是极其重要的组成部分,它们用于处理和操作数据。本篇文章将详细讲解PL/SQL中的单行函数和组函数。 首先,单行函数是针对单行数据进行操作的函数,它们可以应用于SQL查询的不同部分,...

    oracle列合并的实现方法

    在Oracle数据库中,有时我们需要将同一表中多个列的值合并为一个字符串,这被称为列合并。Oracle提供了多种方法来实现这一功能,特别是在不同版本中,这些方法有所不同。以下是Oracle列合并的一些常用方法: 1. **...

    oracle实现行转列功能,并使用逗号进行隔开拼接,成为一条数据.pdf

    Oracle 中实现行转列功能,并使用逗号进行隔开拼接,成为一条数据是指将多行数据合并成一行数据,并用逗号分隔每个字段的值。这种功能在实际应用中非常有用,例如在报表生成、数据分析和数据整合等场景中。 在 ...

    Sql function 多行中的列合并为一行一列的方法

    总结来说,这个示例展示了一种使用SQL自定义函数将多行数据合并为一行的方法,这在处理多值字段时非常有用,但需要注意性能和数据长度限制。在实际应用中,根据数据库系统的特性选择最适合的解决方案是至关重要的。

    sql里将重复行数据合并为一行数据使用逗号进行分隔

    在SQL中,有时我们需要将具有相同属性的重复行数据合并成一行,并使用特定的分隔符,如逗号,来区分各个值。这种操作在处理报告或者数据分析时非常常见,可以减少数据的冗余,使结果更加简洁。本文将详细讲解如何在...

    Oracle行列转换

    这在你需要将一组相关的列合并为一个或多个行时非常有用。基本语法如下: ```sql SELECT column1, unpivot_column, value FROM table UNPIVOT ( value FOR unpivot_column IN (column2, column3, ...) ); ``` 在...

    Oracle行转列

    例如,有一个表t_row_col,其中包含多行数据,需要将这些行数据合并成一个字符串数据。 可以使用LISTAGG函数来实现多行转换成字符串,例如: ```sql SELECT LISTAGG(cn || ',' || cv) WITHIN GROUP (ORDER BY id) ...

Global site tag (gtag.js) - Google Analytics