SQL连接同一文件中不同记录的文本字段

use*_*338 4 sql ibm-midrange

在这里使用DB2讨论iSeries上的文件中的数据.

文件结构如下:

Item     Textline    Text

12755    1           this item
12755    2           is no longer
12755    3           for sale
abc123   1           please use
abc123   2           another code
xyz987   1           obsolete
Run Code Online (Sandbox Code Playgroud)

我试图得到的结果是

   Item     Text

   12755    this item is no longer for sale
   abc123   please use another code
   xyz987   obsolete
Run Code Online (Sandbox Code Playgroud)

所以它按项目代码分组,文本行加起来,无论有多少.

我首先在查询中尝试将文件连接到自身5次(可能有多达5个文本行),但我永远无法让它工作.

我在SQL中尝试了它,但是我无法获得与famileir一起使用的命令以正确使用文本并且我在标准上挣扎将它们添加到一起而不重复文本行.

任何想法的人?

我最后的办法是将这个文件提取5次,每个文件只包含一个不同的文本行,然后根据项目和连接方式将它们全部重新匹配...但是哇多么麻烦:)

请帮忙 :)

War*_*enT 6

DB2 for i可以做到这一点.

也许最简洁的方法是使用一个经常被忽视的特性,其他DB2平台没有 - 一种称为分层查询的递归查询.像许多事情一样,一旦理解它就会相当简单,但理解其工作方式需要一些解释.

递归或分层查询可帮助您将一行连接到一个或多个其他行.在这种情况下,我们正在建立一对一的连接链.

聚合SYS_CONNECT_BY_PATH函数将沿着从起始(或"根")行到结束(或"叶")行的路径连接字符串.

让我们首先将您的示例数据放入表中.

declare global temporary table snippets
( item    varchar(10)
, seq     smallint
, words   varchar(30)
);

insert into snippets  
  values 
   ('12755',  1, 'this item')
  ,('12755',  2, 'is no longer')
  ,('12755',  3, 'for sale')
  ,('abc123', 1, 'please use')
  ,('abc123', 2, 'another code')
  ,('xyz987', 1, 'obsolete')
;
Run Code Online (Sandbox Code Playgroud)

让我们看看我们将用作第一阶段构建块的分层查询.

 SELECT item
      , seq
      , CONNECT_BY_ISLEAF as flag
      , SYS_CONNECT_BY_PATH(words, ' ') as phrase
   FROM snippets
   START WITH seq = 1
   CONNECT BY PRIOR item = item and PRIOR (seq + 1) = seq
Run Code Online (Sandbox Code Playgroud)

CONNECT BY子句定义表中的一列连接条件而异.

所述WITH START子句指定哪个行(多个)以开始从,"根"行接合.所以我们将从seq = 1的行开始,并加入下一个seq值(seq + 1).该行将加入以下seq值,依此类推.

CONNECT_BY_ISLEAF将指示我们何时处于链中的最后一行.你马上就会在这里使用它.

结果如下:

    ITEM   SEQ  FLAG  PHRASE

    12755   1    0    this item
    12755   2    0    this item is no longer
    12755   3    1    this item is no longer for sale
    abc123  1    0    please use
    abc123  2    1    please use another code
    xyz987  1    1    obsolete
Run Code Online (Sandbox Code Playgroud)

现在我们需要做的就是将它放在一个公共表表达式中,我们只能从中获取所需的行.链末尾的"叶子"行有完成的字符串,所以这些是要选择的.

with q as
(
  SELECT item
       , seq
       , CONNECT_BY_ISLEAF as flag
       , SYS_CONNECT_BY_PATH(words, ' ') as phrase
    FROM snippets
    START WITH seq = 1
    CONNECT BY PRIOR item = item and PRIOR (seq + 1) = seq
)
SELECT item
     , phrase
  FROM q
  WHERE flag = 1
  ORDER BY item
;
Run Code Online (Sandbox Code Playgroud)

这给了我们:

    ITEM     PHRASE

    abc123   please use another code    
    xyz987   obsolete   
    12755    this item is no longer for sale    
Run Code Online (Sandbox Code Playgroud)

你有它.

其他DB2平台上的人们必须找到另一种解决方案,例如上面的funkworm评论中的常规递归查询.