SQL:将 substr 与 to_char 一起使用
SQL: using substr along with to_char
我正在使用 Oracle SQL 并且想知道下面的 2 个查询 return 有时是完全相同的结果,有时是不同的结果。
select substr(to_char(min_code + 10, '099'),1,3)
from x
where a = b;
select substr(min_code + 10,1,2)
from x
where a = b;
第一个查询的子字符串长度设置为 3,而第二个查询的子字符串长度设置为 2。但是,当 min_code 等于 151 时,两个查询都将 return 16。这怎么可能?
我意识到这一定与使用 to_char 时 substr 如何计算长度有关,但据我了解,第二个参数(在这些情况下为 1)是子字符串的开始位置,第三个参数是子字符串的长度。然而,第一个查询仍然是 returns 16 而不是我想象的 161。
然后,当我用 min_code 等于 051 的记录对其进行测试时,第一个查询将 return 06,而第二个查询将 return 61。我理解第二个查询得到 61,因为它在执行算术运算时必须删除前导 0 但是第一个查询到底是怎么做的(使用 to_char 函数)return 06。我希望 061 长度为 3。
只需将您的测试放在一个查询中并删除 +10
(问题不存在),这就是您所拥有的:
SQL> with testCases(n) as ( select 151 from dual union select 51 from dual)
2 select n,
3 substr(to_char( n, '099'),1,3) as substr_3,
4 substr(n,1,2) as substr_3
5 from testCases;
N SUBSTR_3 SUBSTR_3
---------- ------------ --------
51 05 51
151 15 15
我相信让您期待不同结果的是 to_char
应该做的事情;为了澄清,请查看以下结果:
SQL> with testCases(n) as ( select 151 from dual union select 51 from dual)
2 select n,
3 '|' || to_char( n, '099') || '|' as to_char
4 from testCases;
N TO_CHA
---------- ------
51 | 051|
151 | 151|
在这里您看到 to_char
在结果字符串中添加了前导 space;这会使您的子字符串逻辑失败,给您带来意想不到的结果。
清楚地解释了此行为 here:
The extra leading space is for the potential minus sign. To remove the
space you can use FM in the format
事实上,如果您编辑格式掩码,您有
SQL> with testCases(n) as ( select 151 from dual union select 51 from dual)
2 select n,
3 '|' || to_char( n, 'FM099') || '|' as to_char
4 from testCases;
N TO_CHA
---------- ------
51 |051|
151 |151|
你的测试用例变成:
SQL> with testCases(n) as ( select 151 from dual union select 51 from dual)
2 select n,
3 substr(to_char( n, 'FM099'),1,3) as substr_3,
4 substr(n,1,2) as substr_2
5 from testCases ;
N SUBSTR_3 SUBSTR_2
---------- ------------ --------
51 051 51
151 151 15
我正在使用 Oracle SQL 并且想知道下面的 2 个查询 return 有时是完全相同的结果,有时是不同的结果。
select substr(to_char(min_code + 10, '099'),1,3)
from x
where a = b;
select substr(min_code + 10,1,2)
from x
where a = b;
第一个查询的子字符串长度设置为 3,而第二个查询的子字符串长度设置为 2。但是,当 min_code 等于 151 时,两个查询都将 return 16。这怎么可能?
我意识到这一定与使用 to_char 时 substr 如何计算长度有关,但据我了解,第二个参数(在这些情况下为 1)是子字符串的开始位置,第三个参数是子字符串的长度。然而,第一个查询仍然是 returns 16 而不是我想象的 161。
然后,当我用 min_code 等于 051 的记录对其进行测试时,第一个查询将 return 06,而第二个查询将 return 61。我理解第二个查询得到 61,因为它在执行算术运算时必须删除前导 0 但是第一个查询到底是怎么做的(使用 to_char 函数)return 06。我希望 061 长度为 3。
只需将您的测试放在一个查询中并删除 +10
(问题不存在),这就是您所拥有的:
SQL> with testCases(n) as ( select 151 from dual union select 51 from dual)
2 select n,
3 substr(to_char( n, '099'),1,3) as substr_3,
4 substr(n,1,2) as substr_3
5 from testCases;
N SUBSTR_3 SUBSTR_3
---------- ------------ --------
51 05 51
151 15 15
我相信让您期待不同结果的是 to_char
应该做的事情;为了澄清,请查看以下结果:
SQL> with testCases(n) as ( select 151 from dual union select 51 from dual)
2 select n,
3 '|' || to_char( n, '099') || '|' as to_char
4 from testCases;
N TO_CHA
---------- ------
51 | 051|
151 | 151|
在这里您看到 to_char
在结果字符串中添加了前导 space;这会使您的子字符串逻辑失败,给您带来意想不到的结果。
清楚地解释了此行为 here:
The extra leading space is for the potential minus sign. To remove the space you can use FM in the format
事实上,如果您编辑格式掩码,您有
SQL> with testCases(n) as ( select 151 from dual union select 51 from dual)
2 select n,
3 '|' || to_char( n, 'FM099') || '|' as to_char
4 from testCases;
N TO_CHA
---------- ------
51 |051|
151 |151|
你的测试用例变成:
SQL> with testCases(n) as ( select 151 from dual union select 51 from dual)
2 select n,
3 substr(to_char( n, 'FM099'),1,3) as substr_3,
4 substr(n,1,2) as substr_2
5 from testCases ;
N SUBSTR_3 SUBSTR_2
---------- ------------ --------
51 051 51
151 151 15