【问题标题】:Find rows which contain special characters except underscore and space查找包含除下划线和空格以外的特殊字符的行
【发布时间】:2015-01-24 09:22:16
【问题描述】:

我有一个包含 210 万行的许多列的表。以下是与我的问题相关的列:

Column_name Type    Computed    Length  Prec    Scale   Nullable    TrimTrailingBlanks  FixedLenNullInSource    Collation
id          int     no          4       10      0       no          (n/a)               (n/a)                   NULL
val         varchar no          15                      yes         no                  yes                     SQL_Latin1_General_CP1_CI_AS

我想在val 列中返回包含A-Z、a-z、0-9、(空格)和_ 以外的字符的行。 样本数据:

INSERT INTO tabl
            (id, val)
VALUES      (1, 'Extemporè'),
            (2, 'Aâkash'),
            (3, 'Driver 12'),
            (4, 'asd'),
            (5, '10'),
            (6, 'My_Car'),
            (7, 'Johnson & Sons'),
            (8, 'Johan''s Service'), 
            (9, 'Indus Truck')

预期输出:

id  val
--  -----------
1   Extemporè
2   Aâkash
7   Johnson & Sons
8   Johan's Service

我发现了类似的问题here,但它也没有给出预期的结果:

SELECT *
FROM   tabl
WHERE  val LIKE '%[^A-Z0-9 _]%' 

给出结果:

id  val
--  ----------
7   Johnson & Sons
8   Johan's Service

【问题讨论】:

  • SELECT * FROM tbl where PATINDEX('%[^a-zA-Z0-9 _]%',Col) > 0
  • @knkarthick24 它给出的结果与我的查询相同,而不是返回 id 为 1 和 2 的行。
  • 你得到了哪些你认为不应该得到的结果?你的排序是什么?试试WHERE val LIKE '%[^a-zA-Z0-9 _]%' COLLATE Latin1_General_CI_AI。其实你可以用'%[^A-Z0-9 _]%'
  • @BaconBits 排序信息在列信息框中给出。我试过你的查询,它也给出了相同的结果。已编辑问题,建议您使用 '%[^A-Z0-9 _]%'。
  • Here 是一个类似的问题。

标签: sql sql-server-2008 tsql


【解决方案1】:

更新答案:使用临时表是为了排除“Driver”或“Indus Truck”等值;临时表还强制对诸如“Aâkash”之类的值进行排序规则更改 - 这是为了确保正确的值不符合在联接中排除的条件。
注意:正确值中包含的特殊字符(例如 ' 或 &)必须手动添加到列表中(如下标记)。

create table #tabl(id int, val varchar(15))

insert #tabl(id, val)
select i.id, cast(i.val as varchar(200)) Collate SQL_Latin1_General_CP1253_CI_AI as val
from tabl i
where i.val <> upper(i.val) Collate SQL_Latin1_General_CP1_CS_AS
    and i.val <> lower(i.val) Collate SQL_Latin1_General_CP1_CS_AS
    and i.val not like '%[0-9]%'
    and i.val not like '%[_]%'
    and i.val not like '%[]%'
    and i.val not like '%[''&]%' -- add special characters (like ' or &) that are permitted in this list; 
                            -- this is the only "manual" requirement for this solution to work.

select t.id, t.val
from tabl t
left join #tabl tt on t.val = tt.val
where tt.val is null
    and t.val <> upper(t.val) Collate SQL_Latin1_General_CP1_CS_AS
    and t.val <> lower(t.val) Collate SQL_Latin1_General_CP1_CS_AS
    and t.val not like '%[0-9]%'
    and t.val not like '%[_]%'
    and t.val not like '%[]%'

【讨论】:

  • 感谢您的回答。我用实际数据检查了您的查询,我发现它也会返回那些包含大写和小写字母组合的记录。例如,如果第 3 行中的数据是 Driver 而不是 Driver 12,那么它将返回我不想要的数据。更新了样本数据中的此类记录。
  • @DeepakPawar,更新了答案以匹配附加规则。请重试并检查注释(值中允许的特殊字符应在列表中识别并注明)。
  • 这将起作用+1,但我刚刚从另一个来源得到答案,它在WHERE val LIKE '%[^abcdefghijklmnopqrstuvwxyz0-9_ ]%' 等搜索字符串中明确定义a-z 字符,我想添加有效字符串比添加有效字符串更容易特殊字符。
【解决方案2】:

我会在诸如 Latin1_General_BIN like this 之类的排序规则的帮助下做到这一点:

SELECT *
FROM   tabl
WHERE  val COLLATE Latin1_General_BIN LIKE '%[^A-Za-z0-9 _]%'

这样看起来会更容易,因为 BIN 排序规则既区分大小写又区分重音,此外,重音字符与非重音字符分开排序。后者意味着很容易以范围的形式指定非重音字母。 (但区分大小写意味着您还必须明确指定两种大小写的字母,如上所示。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    • 2013-01-11
    • 1970-01-01
    • 1970-01-01
    • 2022-12-16
    • 1970-01-01
    相关资源
    最近更新 更多