【问题标题】:Oracle SQL -- Select all but entries that are blank or have spacesOracle SQL -- 选择除空白或有空格的所有条目
【发布时间】:2017-09-07 05:00:25
【问题描述】:

你好,下午好,

我正在尝试编写一个查询来选择多个客户 ID。有时,无论出于何种原因,客户 ID (PK) 可能有一个空白的客户名称,或者一个包含 4 或 5 个空格的客户名称,但没有数字或字母(名称可以是任何数字或字母字符串,有时“ ——”也是)。

如何过滤掉它?除了我的其他 WHERE 子句之外,我当前的查询看起来像这样。我需要确保 CustomerName 不只是一堆空格或空的。它需要有一些字母数字文本,或 -:

   SELECT cust.CustomerID, cust.CustomerName
   FROM cust
   WHERE cust.StartDate Between '01-Jun-2017' AND '01-Sep-2017' AND cust.CustomerID Like '%100%' Or cust.CustomerID Like '%200%'

但是,我希望看起来像这样:

   AND CustomerName NOT LIKE '%  %' OR != ""

任何建议将不胜感激!

【问题讨论】:

  • 使用TRIM函数怎么样?
  • 或替换replace(' this is a test',' ',''), coalesce(replace(' ',' ',''),'x') as ExcludeMe
  • 为什么关于'-'的评论你也想用它做一些特别的事情?
  • @RadimBača 如果可以,请查看我的更新。问题是有时,客户名称字段已输入为“”或“”或“”,我不想要这些结果。
  • @mathguy 你能把这个作为一个完整的回复发布吗?你的回答很完美......我不知道我可以把 TRIM(CustomerName) IS NOT NULL 放在我的选择语句中。你能告诉我正确的语法吗?

标签: sql oracle select


【解决方案1】:

我假设你的查询想要做这样的事情:

AND (CustomerName NOT LIKE '%  %' OR CustomerName != '')

警告!这不会给你一个编译错误,但它不会像你期望的那样工作。 Oracle 会将 '' 解释为 NULL,并且没有什么不等于 NULL(也没有什么等于 NULL)。因此,您的条件的第二部分总是错误的,这使得它毫无用处。为了实现你想要的,你必须使用

OR CustomerName IS NOT NULL

或如上文所述:

OR TRIM(CustomerName) IS NOT NULL

【讨论】:

  • 因此,NOT NULL 分隔那些实际上是空白的,然后 TRIM 删除空格,使那些只包含空格的条目变为空白,从而使其成为 NOT NULL 分隔的牺牲品,对吗?我只是想了解...我尝试从这些经验中学习,而不是重复答案。
  • 是的,它就是这样工作的。您可以省略 TRIM(),因为如果 TRIM 删除空格,则条件 CustomerName NOT LIKE '% %' 将为真。
  • 我的整体声明现在看起来像:SELECT cust.CustomerID, cust.CustomerName FROM cust WHERE cust.StartDate Between '01-Jun-2017' AND '01-Sep-2017' AND cust.CustomerID Like '%100%' 或 cust.CustomerID Like '%200%' AND TRIM(CustomerName IS NOT NULL)
  • @tonykelly 这行得通吗?如果不是,那么记录的长度(trim(customerName))是多少?
  • 没有。我给你的语法是错误的。我的错!我修复了我的帖子。但是,如果您在 where 条件中包含“AND cust.CustomerID Like '%100%' Or cust.CustomerID Like '%200%'”,您将自动排除空格和 NULLS。但你并不排除“200”或“200”。如果你想排除那些你必须添加 AND CustomerID NOT LIKE '% %'。
【解决方案2】:

我认为以下功能可以帮助您解决问题:

TRIM( [ [ LEADING | TRAILING | BOTH ] trim_character FROM ] string1 )

你可能还需要把上面的东西包起来

LENGTH( string1 )

如有任何进一步的说明,请随时询问我!

泰德

【讨论】:

  • 如果可以,请查看我的更新。问题是有时,客户名称字段已输入为“”或“”或“”,我不想要这些结果。
  • 为什么需要LENGTH()? TRIM(...) is not null 就足够了。
  • 是的,你是对的 LENGTH 可能不需要。回到 TRIM,TRIM(BOTH '-' FROM TRIM(BOTH ' ' FROM x)) 怎么样?
  • OP 不希望以任何特定方式处理破折号-,他只是提到“有效”名称可能包括字母、数字,有时破折号。他们不必被处理。只有空格需要处理。然后:默认情况下,TRIM 将从两边修剪(尽管在这个问题中它甚至无关紧要),并且默认情况下,TRIM 将修剪空格。所以 TRIM(customername) 单独,没有其他参数,就足够了!
  • 所以我不明白剩下的未解决问题是什么!?
【解决方案3】:

我认为您只需要在正确的位置使用括号:

SELECT cust.CustomerID, cust.CustomerName
FROM cust
WHERE cust.StartDate Between date '2017-06-01' and date '2017-09-01' and 
      (cust.CustomerID Like '%100%' Or cust.CustomerID Like '%200%')

like 模式要求客户 ID 至少为 100 或 200,因此不允许使用空格和空字符串。

您可能还注意到,我更喜欢使用 ISO 标准格式 YYYY-MM-DD 的日期常量。

或者,如果您愿意:

SELECT cust.CustomerID, cust.CustomerName
FROM cust
WHERE cust.StartDate Between date '2017-06-01' and date '2017-09-01' and 
      regexp_like(cust.CustomerID, '[12]00')

【讨论】:

  • 谢谢。但我想我可能错误地表达了我的问题。第一个查询运行良好。我需要一个额外的 AND 条件,我使用 NOT LIKE 但我不知道语法。
  • 问题是(并且从一开始就是)关于排除 customerid 为 null 或所有空格的行。这个答案与问题无关。
【解决方案4】:

这样的事情将解决上述问题:

where customerId is not null
and customerId > ''
and customerId = , replace(customerId, ' ', '') -- this takes care of the spaces

【讨论】:

  • 这将不返回任何行,因为... > null 从不为真,并且在 Oracle 中,'' 与 null 相同。
【解决方案5】:

最好使用正则表达式:

AND NOT REGEXP_LIKE(CustomerName, '^[[:space:]]*$')

【讨论】:

    猜你喜欢
    • 2012-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多