我有一个Varchar2字段,通常包含两个字母字符(例如ZH
,SZ
,AI
,...)。我们称之为 FOO 。
某些数据集将A
或A1
- A9
保存到同一字段中。我需要选择除了那些之外的所有行。
我使用函数substr
将数字与 A 分开。到目前为止一切顺利,<
或>
似乎无法正常使用&#34;数字字符串&#34; 。
如何在不将其转换为数字的情况下实现此目的?有更简单的解决方案吗?
我还没有在互联网上找到任何东西,我自己也达到了极限。
到目前为止,这是我的 WHERE子句:
WHERE (substr(FOO, 0, 1) != 'A'
or (substr(FOO, 0, 1) = 'A' AND substr(FOO, 1, 1) > '9'));
它无限制地返回所有行。
我找到的唯一解决方案:
WHERE (FOO NOT IN ('A', 'A1', 'A2', 'A3', 'A4', 'A5', 'A6', 'A7', 'A8', 'A9'));
但如果在将来的某个地方有A1
- A50
,那么这不是最佳选择。我必须在 WHERE子句中添加51个字符串。并且,由于查询是源代码,因此代码可读性也会变差。
该解决方案应该适用于ORACLE 和 SQL Server。 提前致谢
答案 0 :(得分:2)
(substr(FOO, 0, 1) = (substr(FOO, 1, 1)
- Oracle从1开始(不是0)。
因此,您应该使用substr(FOO, 2, 1)
来获取第二个符号。
但是,它在具有SUBSTRING(不是SUBSTR)的SQL Server中不起作用。
如果你准备在不同的数据库中使用不同的方法,你也可以尝试使用正则表达式:
的Oracle
where not regexp_like(foo, '^A[1-9]{1,3}$')
^开头的字符串
$字符串的结尾
[1-9]从1到9的任何数字
{1,3}重复前面的表达1,2或3次
匹配/不匹配的FOO示例'^A[1-9]{1,3}$'
a123
- 可能匹配/可能不匹配(取决于区分大小写的NLS设置)
A123
- 匹配(第一个符号为&#39; A&#39;,其他为3个数字)
A123b
- 不匹配(最后一个符号应为数字)
A1234
- 不匹配(结尾应该有1,2或3位数)
A12
- 匹配
A1
- 匹配
SQL Server
REGEXP_LIKE conversion in SQL Server T-SQL
答案 1 :(得分:0)
如果您的要求是包含所有字母值,除了&#39; A&#39;单独考虑使用LIKE表达式,以便它可以与任何符合ANSI标准的DBMS一起使用:
WHERE FOO <> 'A' AND FOO NOT LIKE '%[^A-Z]%'