SQL 字符串比较 - 如何忽略空格

Posted

技术标签:

【中文标题】SQL 字符串比较 - 如何忽略空格【英文标题】:SQL string comparison -how to ignore blank spaces 【发布时间】:2015-11-17 14:50:12 【问题描述】:

我准备了一个 SQL 查询,我必须在多个数据库(Oracle 和 Sybase)上运行,其中一些数据可能以不同的方式存储。

我注意到数据存储的差异之一是空白字符串。 比如下面的PRODUCT_TYPE一栏,请看第二条记录:

这个用红色圈起来的“空字符串”(数据类型为CHAR(15))在某些数据库中等于'',而在其他一些数据库中等于' '。长度永远不会是恒定的,并且有几个字段的行为是这样的。

所以,由于我需要过滤这些“空字符串”,我应该在我的WHERE 子句中更改以下语句:

WHERE PRODUCT_TYPE = ''

...因为上面将' ' 字符串与'' 不同,即使“功能上”不是这样。 因此,我想以“忽略空格”的方式发表声明,即 ' ' 等于 '' 等于 ' ' 等。 我应该如何进行此更改以使其正常工作?

我尝试了简单的替换方法:

WHERE REPLACE(PRODUCT_TYPE,' ','') = ''

...但它似乎不起作用,可能是因为我应该使用不同的字符。 为了测试,在下面的' 中有一个我在这些“空字符串”中找到的复制粘贴示例:

'               '

理想情况下,它应该是“非特定 SQL”解决方案,因为我必须在 Oracle 和 Sybase RDBMS 上运行相同的查询。任何的想法?

【问题讨论】:

为什么两个数据库的查询必须完全相同? 如果REPLACE(PRODUCT_TYPE,' ','') 没有删除所有空格,那么您的字符与空格不同,例如回车或制表符或其他一些不可打印的字符。 @Thilo 这只是结果如何产生的问题。如果我们运行两种类型的查询(一种针对所有 Oracle 数据库,一种针对所有 Sybase 数据库,我们将获得两个单独的文件进行分析)。除非不能做出 IF Oracle ELSE 语句?我承认我不太擅长 SQL,希望您能在这方面提出建议。 拥有两个独立查询的想法是能够从它们中获取相同的标准化文件(以一种比尝试对两者都适用的单个查询更容易实现的方式)。我不确定哪种方式更适合这里。无论哪种方式,与多个数据库供应商合作都很麻烦,尤其是当您无法控制数据如何首先进入数据库时​​。 @MatteoNNZ 我明白了。现在你有一个强有力的技术想法来解释你的利益相关者。我赞成我认为好的和有帮助的答案。另外,赞成你的问题。顺便说一句,请确保下次您提供 create 和 insert 语句作为示例数据。或者,至少是一个带有示例模式的 SQL Fiddle。一切顺利:-) 【参考方案1】:

您可以在列上使用trim

where trim(product_type) is null

以上内容与 DBMS 无关,因为 Sybase 不提供 trim 函数。 但是,以下方法在 Sybase 和 Oracle 中都适用:

where rtrim(ltrim(product_type)) is null

【讨论】:

感谢 vkp。这很有效,这是我将要遵循的方法,因为它是最易读的。 在 Sybase 上是否也“修剪为 NULL”? @Thilo 实际上,它告诉我“未找到函数 'trim'”。我将不得不尝试 REPLACE 方法,尽管我更喜欢这种方法。 @MatteoNNZ 您是否尝试过检查 LTRIM 和 RTRIM 是否独立存在?一些 DBMS 只实现这 2 个而不是它们的组合 (TRIM)。 @JulienBlanchard 是的,我正要写这个。通过结合 LTRIM 和 RTRIM,我得到了我正在寻找的独立于 DBMS 的解决方案。【参考方案2】:

您可以使用您尝试过的替换语句,但您应该测试“is null”而不是 =''

WHERE REPLACE(PRODUCT_TYPE,' ','') is null

另请参阅: null vs empty string in Oracle

【讨论】:

感谢 Rene,这行得通。我更喜欢使用trim 的vkp 解决方案(只是为了便于阅读),但非常感谢您的帮助。这仍然是一个有效的答案,如果我能接受 2 我会接受 :)【参考方案3】:

简单的(和非 DBMS 特定的)答案是:

不要不要使用CHAR(15)

char(n) 是一个固定长度的数据类型。因此,无论您在其中存储什么,该值都将始终填充到定义的长度。如果您存储单个字符,DBMS 将存储该单个字符和 14 个空格。

将您的列更改为使用varchar(15),您应该不会有任何问题。

【讨论】:

反之,char(15)中怎么会存在一个空格? @Thilo:理论上不能,但是有些 DBMS 不符合 ANSI 标准,并且将存储的值填充到定义的长度(Microsoft 和 Sybase 浮现在脑海中)。但是我知道没有 DBMS 将 varchar 列填充到定义的长度 OTOH,在 Oracle 中,空字符串根本无法存储(它变为 NULL)。也好不到哪里去。 不幸的是,更改数据类型不在我这边的讨论范围内(我只能读取数据库)。但我同意你的观点,这是错误的数据类型,它实际上已经得到改进,但不幸的是我仍然需要在一些仍然存在这个问题的旧数据库上运行我的查询。 我完全同意@a_horse_with_no_name,我认为没有任何理由使用CHAR 数据类型?它是一种固定长度的数据类型,这意味着您将总是消耗额外的存储空间,即使您不需要它。像往常一样 +1

以上是关于SQL 字符串比较 - 如何忽略空格的主要内容,如果未能解决你的问题,请参考以下文章

比较字符串忽略开头或结尾处的空格

比较不包括标点符号和空格的字符串

如何在java中对字符串进行排序时忽略空格?

SQLServer中比较末尾带有空格的字符串

每日算法刷题Day7-比较字符串大小,去掉多余的空格,单词替换

在Visual Studio / TFS中比较源时如何忽略空格?