【问题标题】:SQL: match a string pattern irrespective of it's case, whitespaces in a columnSQL:匹配字符串模式,不考虑大小写,列中的空格
【发布时间】:2015-04-29 09:56:31
【问题描述】:

我需要在列中找到字符串的频率,而不管它的大小写和任何空格。

例如,如果我的字符串是My Tec Bits,并且它们像这样出现在我的表中,如下所示:

061  MYTECBITS    12123
102  mytecbits    24324
103  MY TEC BITS  23432
247  my tec bits  23243
355  My Tec Bits  23424
454  My Tec BitS  23432

然后,输出应该是6,因为去掉了白人的步伐并且不考虑大小写,所有这些字符串都是相同的。

SQL 中是否有与 R 中相同的 grep()

【问题讨论】:

  • 您使用的是 MySQL 还是 Oracle?除非您同时使用两个数据库,否则不应添加两个标签。
  • 请注意,在 MySQL 中 REGEXP 默认不区分大小写。
  • @CasimiretHippolyte - 区分大小写取决于被测试列的COLLATION
  • @RickJames:我只能是二进制排序规则的问题,但在这种情况下,您可以使用COLLATE 关键字人为地更改它以进行字符串搜索。但正如我所说,默认情况下SELECT "a" REGEXP "A"; 返回 1
  • 很好的例子。但是...SET @@collation_connection = utf8_bin; SELECT "a" REGEXP "A"; 返回 0。因此,我声称是排序规则、正则表达式决定了是否折叠。

标签: mysql sql regex agrep


【解决方案1】:

如果您只关心 SPACECASE,那么您需要两个函数:

  • 替换
  • 上/下

例如,

SQL> WITH DATA AS(
  2  SELECT 'MYTECBITS' STR FROM DUAL UNION ALL
  3  SELECT 'mytecbits' STR FROM DUAL UNION ALL
  4  SELECT 'MY TEC BITS' STR FROM DUAL UNION ALL
  5  SELECT 'my tec bits' STR FROM DUAL UNION ALL
  6  SELECT 'MY TEC BITS' STR FROM DUAL UNION ALL
  7  SELECT 'MY TEC BITS' STR FROM DUAL
  8  )
  9  SELECT UPPER(REPLACE(STR, ' ', '')) FROM DATA
 10  /

UPPER(REPLA
-----------
MYTECBITS
MYTECBITS
MYTECBITS
MYTECBITS
MYTECBITS
MYTECBITS

6 rows selected.

SQL>

那么,输出应该是6

因此,基于此,您需要在 过滤谓词COUNT(*) 中使用它返回的行:

SQL> WITH DATA AS(
  2  SELECT 'MYTECBITS' STR FROM DUAL UNION ALL
  3  SELECT 'mytecbits' STR FROM DUAL UNION ALL
  4  SELECT 'MY TEC BITS' STR FROM DUAL UNION ALL
  5  SELECT 'my tec bits' STR FROM DUAL UNION ALL
  6  SELECT 'MY TEC BITS' STR FROM DUAL UNION ALL
  7  SELECT 'MY TEC BITS' STR FROM DUAL
  8  )
  9  SELECT COUNT(*) FROM DATA
 10  WHERE UPPER(REPLACE(STR, ' ', '')) = 'MYTECBITS'
 11  /

  COUNT(*)
----------
         6

SQL>

注意WITH 子句仅用于构建示例表 用于演示 目的。在我们的实际查询中,删除整个 WITH 部分,并在 FROM 子句中使用您的 actual table_name

所以,你只需要这样做:

SELECT COUNT(*) FROM YOUR_TABLE 
  WHERE UPPER(REPLACE(STR, ' ', '')) = 'MYTECBITS'
/

【讨论】:

  • 我认为使用WITH DATA AS 会使您的答案过于复杂。
  • @Eilidh 那么当 OP 不提供任何样本数据时该怎么办。这里的WITH子句只是为了建表演示。不要混淆。当样本数据不可用时,我们使用 WITH 子句进行演示。这是你投反对票的原因吗?
  • 我并不感到困惑,我知道您为什么使用 WITH 子句,但是 OP 表示它们对 SQL 来说非常新,并且在您的回答中显示这一点对于 OP 的问题来说是不必要的,并且会混淆重要的零件。
  • @Eilidh 重要部分已作为要点提到。无论如何,我在最后添加一个关于 WITH 子句的注释,如果这让你感到舒服的话。
  • 抱歉没有提及表名并造成混乱。把它放在一个非常清晰的方式。 @christian-barron 的答案也正是我一直在寻找的东西..
【解决方案2】:

你可以使用类似的东西

UPPER(REPLACE(userString, ' ', ''))

仅检查大写字母并删除空格。

【讨论】:

    【解决方案3】:

    在比较它们之前,您可以将语句转换为 LOWER()。

    LOWER(column_name) = LOWER(variable)
    

    更具体:

    LOWER(First_name) = LOWER('JoHn DoE')
    

    将成为名字 = 'john doe'

    对于应使用替换的间距,其格式为:

    REPLACE(yourstring, ' ' , '')
    

    ' ' = 空格字符替换为空字符串 = ''

    所以你会这样做

    WHERE LOWER(REPLACE(fieldname, ' ', '') = 'mytecbits'
    

    【讨论】:

    • 如果COLLATION 是“..._ci”,则LOWER() 是不必要的,并且会破坏索引的使用。
    • 老实说,我不得不查找排序规则到底是什么,但这意味着您将无法正确检查区分大小写(我将在这里进行有根据的猜测并假设ci 代表不区分大小写),您以后可能想要这样做,或者您可以为每个查询设置排序规则?
    • 排序规则通常默认用于列,然后被遗忘。您可以在比较中使用COLLATION ... 子句,但这种情况非常少见。我对您(以及该线程中的其他所有人)的观点是,fieldname 可能的排序规则消除了对 LOWER() 的需要。 大多数人会混淆“字符集”和“排序规则”。
    【解决方案4】:

    你需要用count来把受影响的数字带回来,Lower会把数据变成小写,这样你比较的时候就可以把它变成小写.

    要删除空格,请使用 Replace 并将空格替换为空字符串以进行比较:

    Select COUNT(ColumnA) 
    from table 
    where Lower(Replace(ColumnB, ' ', '')) = 'mytecbits'
    

    【讨论】:

    • 这也将匹配my other technology bits。他只想忽略空格,不允许其他文本。
    • 谢谢,我没有意识到他只想忽略单个空格。相应更新
    • 哈哈.. 这不是错字.. 顺便说一句,使用 'my%tech%bits' 打开了一个新的维度,希望我有新的东西要学。
    【解决方案5】:

    如果您正在寻找一个特定字符串的实例数,无论大小写/空格如何,那么您需要执行以下操作 -

    • 忽略空格

    • 忽略大小写

    • 统计字符串的实例数

    所以你想要一个像下面这样的查询 -

    SELECT 
        COUNT(field)
    FROM
        table
    WHERE
        UPPERCASE(REPLACE(field, ' ', '')) = UPPERCASE(REPLACE(userstring, ' ', ''))
    

    这会计算表中fielduserstring 相同的行数,当忽略大小写时(所有使用UPPERCASE 设置为相同大小写,因此它被有效地忽略)和空格被忽略(使用REPLACEfielduserstring 中删除空格)

    【讨论】:

    • 是的,它有帮助。欣赏它@Eilidh
    【解决方案6】:

    由于 REGEXP 不区分大小写,您可以通过将空格设为可选来获得匹配,例如:

    SELECT count(field) FROM yourtable WHERE field REGEXP "MY *TEC *BITS";
    

    注意:如果需要,您可以在“MY”之前添加一个空格或[[:<:]](单词边界),在“BITS”之后添加一个空格或[[:>:]],以避免误报。

    【讨论】:

      猜你喜欢
      • 2015-12-16
      • 1970-01-01
      • 1970-01-01
      • 2022-11-20
      • 2014-09-07
      • 2010-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多