我需要帮助我正在尝试运行的SQL语句,我已经做了很多阅读和测试,但我无法得到正确的结果,因此我的请求在这里。
我正在尝试从已从两个源连接数据的列中提取数据,我想在&之前分离数据。加入后,加入是一个' - ' (带有空格的连字符),在此之前或之后可以有字母数字字符' - '这是我需要的数据。只是为了增加复杂性,一些行没有连接数据,即没有' - '当满足要求时,可以简单地提取整个列值并将其视为BB侧(参见下面的第一个BB示例)。
因此,当我结束时,我希望分离AA侧(在 - 之前)和BB侧(在 - 之后)允许单个BB情况。
查看数据可能会出现以下情况。
BB<br>
AA - BB<br>
AA-aa - BB<br>
AA - BB-bb-cc<br>
AA-aa - BB-bb-cc<br>
我可以让代码工作但不能始终如一地满足以上所有要求 - 你能否提出正确的代码,或者即使有更好的解决方案也不会影响SQL性能。
我一直在尝试AA方面的例子: -
工作:
select substr('AA - BB-bb', 0, instr('AA - BB-bb', ' - ', 1, 1)-1) AS A_NAME
from DUAL;
失败(只获得AA,而不是AA-aa):
select substr('AA-aa - BB-bb', 0,instr('AA-aa - BB-bb', ' - ', 1, 1)-1) AS A_NAME
from DUAL;
我一直在尝试BB方面的例子: -
失败:
select SUBSTR('AA-aa - WHENEHEH', INSTR('AA-aa - WHENEHEH',' - ', -1, 1)+1, 100)
B_NAME from dual;
谢谢,马克。
答案 0 :(得分:1)
如果你的分离器确定gona是“爆炸两边的空间”
然后你可以使用CHR()函数。
从您的尝试
select substr('AA-aa - BB-bb', 0,instr('AA-aa - BB-bb', ' - ', 1, 1)-1) AS A_NAME
from DUAL;
使用类似的东西
select substr('AA-aa - BB-bb',0,instr('AA-aa - BB-bb',chr(32))-1) from dual; /* ASCII value for space is chr(32) /*
AA-AA
select substr('AA-aa - BB-bb',instr('AA-aa - BB-bb',chr(32))+2,10) from dual;
“ - BB”
答案 1 :(得分:0)
假设,如您的方案列表所示,模式&#39; - BB&#39;可以依赖,你可以用它来找到分裂。
WITH
DATA AS (
SELECT 'BB' text FROM dual
UNION ALL SELECT 'AA - BB' FROM dual
UNION ALL SELECT 'AA-aa - BB' FROM dual
UNION ALL SELECT 'AA - BB-bb-cc' FROM dual
UNION ALL SELECT 'AA-aa - BB-bb-cc' FROM dual
),
break AS (
SELECT text, instr(text, '- BB') breakpos FROM DATA
)
SELECT
text,
CASE WHEN breakpos = 0 THEN NULL ELSE substr( text, 1, breakpos-1 ) END aa_side,
case when breakpos = 0 then text else substr( text, breakpos+2) end bb_side
FROM break
;
答案 2 :(得分:0)
单个值的条件显示在第二列而不是第一列有点奇怪,但这应该做你需要的其他一切:
with testdata as (
select 'BB' as input_col, 1 as row_num from dual
union
select 'AA - BB', 2 from dual
union
select 'AA-aa - BB',3 from dual
)
select testdata.row_num,
case when (regexp_instr(testdata.input_col,'(\ -\ )') > 0) then
regexp_replace(testdata.input_col, '(.*)(\ -\ )(.*)$', '\1')
else null
end output_col1,
regexp_replace(testdata.input_col, '(.*)(\ -\ )(.*)$', '\3') as output_col2
from testdata
order by testdata.row_num;
编辑:我修改了上面的内容以添加案例检查。我承认通过regexp_replace本身可能有一种更有说服力的方法,但这也有效。
答案 3 :(得分:0)
我觉得这些东西对你有用。 (我希望我明白你的要求) 我用你提到的所有例子尝试了查询,但效果很好。
SELECT REGEXP_SUBSTR ('AA-aa - BB-bb-cc',
'[^ - ]+')
"Right Side",
SUBSTR ('AA-aa - BB-bb-cc',
INSTR ('AA-aa - BB-bb-cc',
' - ')
+ 2)
"Left Side"
FROM DUAL;
这个适用于除BB之外的所有内容,作为解决方法,您可以检查分隔符是否存在,如果不存在,您可以将整个值用于右侧。
SELECT SUBSTR ('AA aa - BB',0,
INSTR ('AA aa - BB',
' - ')
)
"Right Side",
SUBSTR('AA aa - BB',INSTR('AA aa - BB',
' - ')+2)
"Left Side"
FROM DUAL;