Oracle SQL将值拆分为列

时间:2016-12-02 09:41:16

标签: sql oracle split

在Oracle SQL脚本中解决此类问题的建议是什么:

我有一个查询,该查询检索特定PO的附件,此附件(作为查询结果)看起来像这样: 项目:xxxxxxx 任务:yyyyyy 描述:rrrrrr 信息:qqqqqqq

所以基本上它是一套预先制定的价值观。

所以我的问题是 - 是否可以按每个列以某种方式拆分它而不是将这些提到的值作为一个单元格值, 所以上述结果将是: column项目的值为xxxx,列任务的值为yyyyy等。

我知道,我可以使用多个子选择,然后使用SUBSTR和INSTR函数,但只是想一想 - 还有其他方法可以让它更快吗?特别是,如果这样的话,那么#34;列"可能会更多,他们可以动态改变(例如,一个将有任务,但其他没有)?

2 个答案:

答案 0 :(得分:3)

您可以使用REGEXP_SUBSTR执行此操作:

WITH sample_data AS (SELECT 1 ID, 'Project: xxxxxxx Task: yyyyyy Description: rrrrrr Info: qqqqqqq' str FROM dual UNION ALL
                     SELECT 2 ID, 'Project: abcdef Description: fred Info: bloggs' str FROM dual UNION ALL
                     SELECT 3 ID, 'Task: be awesome. Project: the best project ever! Description: my special project Info: only for the best people' str FROM dual UNION ALL
                     SELECT 4 ID, 'Project: Description: james' str FROM dual UNION ALL
                     SELECT 5 ID, 'Project: 151069Task: 99.6Product: Customized something-or-other' str FROM dual)
SELECT ID,
       str,
       regexp_substr(str, 'Project: (.*?)( *Task:| *Description:| *Info:| *$)', 1, 1, NULL, 1) PROJECT,
       regexp_substr(str, 'Task: (.*?)( *Project:| *Description:| *Info:| *$)', 1, 1, NULL, 1) task,
       regexp_substr(str, 'Description: (.*?)( *Project:| *Task:| *Info:| *$)', 1, 1, NULL, 1) description,
       regexp_substr(str, 'Info: (.*?)( *Project:| *Description:| *Task:|$)', 1, 1, NULL, 1) info
FROM   sample_data;

结果:

        ID STR                                                                              PROJECT                                                                          TASK                                                                             DESCRIPTION                                                                      INFO
---------- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- --------------------------------------------------------------------------------
         1 Project: xxxxxxx Task: yyyyyy Description: rrrrrr Info: qqqqqqq                  xxxxxxx                                                                          yyyyyy                                                                           rrrrrr                                                                           qqqqqqq
         2 Project: abcdef Description: fred Info: bloggs                                   abcdef                                                                                                                                                            fred                                                                             bloggs
         3 Task: be awesome. Project: the best project ever! Description: my special projec the best project ever!                                                           be awesome.                                                                      my special project                                                               only for the best people
         4 Project: Description: james                                                                                                                                                                                                                        james                                                                            
         5 Project: 151069Task: 99.6Product: Customized something-or-other                  151069                                                                           99.6Product: Customized something-or-other

每个regexp_substr都以相同的方式工作。以生成项目列的那个为例:

找到后跟一些(或没有)字符的模式Project:,我们将其置于括号内以确定第一个子表达式:(.*?)。 然后我们检查单词Task:Description:Info:或行尾($),每个单词可能会或可能不会在零之前或之后空格(*)。

然后我们将搜索位置和出现指定为1,将match参数指定为null,将输出子表达式指定为1,因为我们只想返回我们在开始时定义的(.*?)表示的单词搜索模式。瞧!

通过这样做,关键词出现在哪个顺序并不重要,regexp_substr将能够为每个关键词提取你所追求的正确单词。 / p>

一个警告是,您需要知道您希望返回的列数,但您希望这会在您的数据中明确定义。

使用\ n(换行符)的分隔符,您可以执行此操作,这样更灵活:

WITH sample_data AS (SELECT 1 ID, 'Project: xxxxxxx'||chr(10)||'Task: yyyyyy'||chr(10)||'Description: rrrrrr'||chr(10)||'Info: qqqqqqq' str FROM dual UNION ALL
                     SELECT 2 ID, 'Project: abcdef'||chr(10)||'Description: fred'||chr(10)||'Info: bloggs' str FROM dual UNION ALL
                     SELECT 3 ID, 'Task: be awesome.'||chr(10)||'Project: the best project ever!'||chr(10)||'Description: my special project'||chr(10)||'Info: only for the best people' str FROM dual UNION ALL
                     SELECT 4 ID, 'Project:'||chr(10)||'Description: james' str FROM dual UNION ALL
                     SELECT 5 ID, 'Project: 151069'||chr(10)||'Task: 99.6'||chr(10)||'Product: Customized something-or-other' str FROM dual)
SELECT ID,
       str,
       regexp_substr(str, 'Project:( *)(.*)', 1, 1, NULL, 2) PROJECT,
       regexp_substr(str, 'Task:( *)(.*)', 1, 1, NULL, 2) task,
       regexp_substr(str, 'Info:( *)(.*)', 1, 1, NULL, 2) info
FROM   sample_data;

结果:

        ID STR                                                                              PROJECT                                                                          TASK                                                                             INFO
---------- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- --------------------------------------------------------------------------------
         1 Project: xxxxxxx                                                                 xxxxxxx                                                                          yyyyyy                                                                           qqqqqqq
           Task: yyyyyy                                                                                                                                                                                                                                       
           Description: rrrrrr                                                                                                                                                                                                                                
           Info: qqqqqqq                                                                                                                                                                                                                                      
         2 Project: abcdef                                                                  abcdef                                                                                                                                                            bloggs
           Description: fred                                                                                                                                                                                                                                  
           Info: bloggs                                                                                                                                                                                                                                       
         3 Task: be awesome.                                                                the best project ever!                                                           be awesome.                                                                      only for the best people
           Project: the best project ever!                                                                                                                                                                                                                    
           Description: my special project                                                                                                                                                                                                                    
           Info: only for the best people                                                                                                                                                                                                                     
         4 Project:                                                                                                                                                                                                                                           
           Description: james                                                                                                                                                                                                                                 
         5 Project: 151069                                                                  151069                                                                           99.6                                                                             
           Task: 99.6                                                                                                                                                                                                                                         
           Product: Customized something-or-other

您可以使用任何不会在每个关键字的值中出现的字符作为分隔符,并在上一个查询中使用该字符代替\ n。

答案 1 :(得分:-1)

但是对于我所收集的内容,你有相同的性格来分隔价值观。为此,您可以使用ListAgg函数:

SELECT LISTAGG(column, ': ')
         WITHIN GROUP (ORDER BY name) "List",
   FROM table;