在Oracle SQL脚本中解决此类问题的建议是什么:
我有一个查询,该查询检索特定PO的附件,此附件(作为查询结果)看起来像这样: 项目:xxxxxxx 任务:yyyyyy 描述:rrrrrr 信息:qqqqqqq
所以基本上它是一套预先制定的价值观。
所以我的问题是 - 是否可以按每个列以某种方式拆分它而不是将这些提到的值作为一个单元格值, 所以上述结果将是: column项目的值为xxxx,列任务的值为yyyyy等。
我知道,我可以使用多个子选择,然后使用SUBSTR和INSTR函数,但只是想一想 - 还有其他方法可以让它更快吗?特别是,如果这样的话,那么#34;列"可能会更多,他们可以动态改变(例如,一个将有任务,但其他没有)?
答案 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;