【问题标题】:Oracle equivalent to SQL Server STUFF function?oracle相当于SQL Server STUFF函数?
【发布时间】:2011-01-07 16:03:17
【问题描述】:

Oracle 是否有自己的 SQL Server stuff 函数实现?

Stuff 允许您从多行选择中接收一个值。下面考虑我的情况

 ID   HOUSE_REF   PERSON
 1      A         Dave
 2      A         John
 3      B         Bob

我想编写一个 select 语句,但我希望 PERSON 名称位于一行中。

例如,当我从这个表中选择时,我想实现如下

HOUSE_REF   PERSONS
A           Dave, John
B           Bob

到目前为止,我还没有找到一个简单的解决方案,可能是编写我自己的函数来使用,但我不完全确定如何解决这个问题,有什么想法吗?

它的主要业务用途是有一个选择语句来显示每所房子,并针对该房子有一个列,列出住在该房子里的每个人。此选择中的房屋引用必须是唯一的,因此需要连接人员

谢谢

【问题讨论】:

  • 您误解了 T-SQL STUFF 的作用。请参阅文档:technet.microsoft.com/en-us/library/ms188043.aspx。它可以用作您尝试做的解决方案的一部分,但它本身并不是解决方案。
  • 与 Oracle 无关 - 但 MySQL 有一个名为 GROUP_CONCAT 的函数似乎可以解决上述问题。

标签: oracle select


【解决方案1】:

您可以编写自定义聚合函数来执行此操作。您生成的此字符串限制为 4k 个字符。

http://www.sqlsnippets.com/en/topic-11591.html

有一个未记录的、不受支持的函数 WMSYS.WM_CONCAT 可以做同样的事情。

http://www.psoug.org/reference/undocumented.html

【讨论】:

【解决方案2】:

Oracle 11.2 包含一个新函数 LISTAGG 来执行此操作。

在此之前您可以使用Tom Kyte's STRAGG function

【讨论】:

【解决方案3】:

“没有附加组件/没有未记录的功能”Oracle 解决方案(在 Tony 提到的 11.2 之前)是:

select c1, ltrim(sys_connect_by_path(c2,','),',') persons
 from
  (
   select c1, c2, 
    row_number() over (partition by c1 order by c2 ) rn
     from
      (
       select house_ref c1, person c2 
        from housetable 
      )
   )
  where connect_by_isleaf=1
  connect by prior rn+1 =rn and prior c1 = c1
  start with rn=1
;

【讨论】:

    【解决方案4】:

    执行以下三个函数。

    功能1

    创建或替换类型 stragg_type 为 对象(字符串 varchar2(4000),

    静态函数 ODCIAggregateInitialize ( sctx in out stragg_type ) 返回号码,

    成员函数 ODCIAggregateIterate ( self in out stragg_type , varchar2 中的值 ) 返回号码,

    成员函数 ODCIAggregateTerminate (自我在 stragg_type, 返回值输出 varchar2, 标志数量 ) 返回号码,

    成员函数 ODCIAggregateMerge ( self in out stragg_type, stragg_type 中的 ctx2 ) 返回号码 );

    /

    功能2

    创建或替换类型体 stragg_type 是

    静态函数 ODCIAggregateInitialize ( sctx in out stragg_type ) 返回数为 开始

    sctx := stragg_type( null ) ;
    
    return ODCIConst.Success ;
    

    结束;

    成员函数 ODCIAggregateIterate ( self in out stragg_type , varchar2 中的值)返回编号开始

    self.string := self.string || ',' || value ;
    
    return ODCIConst.Success;
    

    结束;

    成员函数 ODCIAggregateTerminate ( 自我
    在 stragg_type 中, 返回值 out varchar2 , 编号中的标志)返回编号开始

    returnValue := ltrim( self.string, ',' );
    
    return ODCIConst.Success;
    

    结束;

    成员函数 ODCIAggregateMerge
    ( self in out stragg_type , ctx2 in stragg_type ) 返回编号开始

    self.string := self.string || ctx2.string;
    
    return ODCIConst.Success;
    

    结束;

    结束; /

    功能3

    创建或替换函数 stragg ( 输入 varchar2 ) 返回 varchar2
    确定性并行启用
    使用 stragg_type 聚合; /


    执行三个函数后,现在你可以使用 stragg 如下

    示例表:emp name |工资a
    | 100 个 | 200个| 300 b | 400 乙 | 500 摄氏度 | 600 摄氏度 | 700天
    | 800

    选择姓名,STRAGG(salary) as 按名称来自 emp 组的字符串;

    输出:

    一个 | 100,200,300

    b | 400,500

    c | 600,700

    d | 800

    【讨论】:

    猜你喜欢
    • 2023-02-23
    • 2010-12-30
    • 1970-01-01
    • 2016-03-08
    • 1970-01-01
    • 1970-01-01
    • 2010-11-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多