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

2024-03-09

我们正在讨论使用 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

我想要得到的结果是

   Item     Text

   12755    this item is no longer for sale
   abc123   please use another code
   xyz987   obsolete

因此它是按项目代码分组的,并且无论有多少文本行都会相加。

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

我在 SQL 中尝试过,但无法使用我熟悉的命令来正确处理文本,并且我正在努力寻找将它们添加在一起而不重复文本行的标准。

有人有什么想法吗?

我的最后一招是将该文件提取 5 次,每个文件只包含不同的文本行,然后根据项目将它们全部匹配在一起并以这种方式连接...但是哇,这有多混乱:)

请帮忙 :)


DB2 for i 可以做到这一点。

也许最简洁的方法是使用一个经常被忽视的功能,这是其他 DB2 平台所没有的——一种称为递归查询的类型。分层查询 http://pic.dhe.ibm.com/infocenter/iseries/v7r1m0/topic/db2/rbafzhierquerycl.htm。像许多事情一样,一旦你理解了它,它就相当简单,但需要一些解释才能理解它是如何工作的。

递归或分层查询可帮助您将一行连接到一行或多行。在本例中,我们正在建立一对一连接的链。

总计SYS_CONNECT_BY_PATH 函数 http://pic.dhe.ibm.com/infocenter/iseries/v7r1m0/topic/db2/rbafzscasys_cby_path.htm将沿着从起始(或“根”)行到结束(或“叶”)行的路径连接字符串。

让我们首先将示例数据放入表中。

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')
;

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

 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

The 连接方式 http://pic.dhe.ibm.com/infocenter/iseries/v7r1m0/topic/db2/rbafzcbyroot.htm子句定义从表中的一行到另一行的连接条件。

The 从...开始 http://pic.dhe.ibm.com/infocenter/iseries/v7r1m0/topic/db2/rbafzhierquerycl.htm子句指定从“根”行开始连接的行。因此,我们将从 seq=1 的行开始,并连接到下一个 seq 值 (seq+1)。该行将连接到以下 seq 值,依此类推。

CONNECT_BY_ISLEAF http://pic.dhe.ibm.com/infocenter/iseries/v7r1m0/topic/db2/rbafzpseudocol.htm将指示我们何时位于链中的最后一行。稍后您就会明白我为什么在这里使用它。

结果如下:

    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

现在我们需要做的就是将其放入公用表表达式 http://pic.dhe.ibm.com/infocenter/iseries/v7r1m0/topic/db2/rbafzcomtexp.htm, 我们只能从中取出我们想要的行。链末端的“叶子”行具有完整的字符串,因此这些是要挑选的。

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
;

这给了我们:

    ITEM     PHRASE

    abc123   please use another code    
    xyz987   obsolete   
    12755    this item is no longer for sale    

你有它。

使用其他 DB2 平台的人们将不得不寻找另一种解决方案,例如常规递归查询funkworm https://stackoverflow.com/users/2684660/funkwurm上面的评论。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐