【问题标题】:SELECT specific characters from column SQL从 SQL 列中选择特定字符
【发布时间】:2016-03-16 10:10:05
【问题描述】:

我在BOOKS 表中有列名BOOKNAME,它可以包含许多除字母数字之外的特殊字符,例如',$#()[],

如何编写查询以仅显示所有行中的特殊字符并将它们联合起来,例如

Row number Book name   
1           Alice$inWonder(Land)
2           Tom Harry#$%^& adventures

所以查询应该显示像$()#%^&这样的输出

我试过了,但不明白为什么它不只显示这些字符

SELECT replace(BOOKNAME , '%[^a-zA-Z0-9 ]%', '') FROM BOOKS 
WHERE BOOKNAME like '%[^a-zA-Z0-9 ]%'

【问题讨论】:

  • 我们可以使用 STUFF、PATINDEX 吗?

标签: sql sql-server regex


【解决方案1】:

为方便起见,您可以创建一个用户定义的函数来选择特殊字符,如下所示:

用户自定义函数:[dbo].[SpecialCharacters]

create Function [dbo].[SpecialCharacters](@res VarChar(1000))
returns varchar(1000)
as
begin

declare @str as varchar(50)
set @str = '%[a-z]%'
while patindex(@str, @res) > 0
set @res = stuff(@res, patindex(@str, @res), 1, '')

return @res
End 

那么,

select '' + stuff((select t.specialchars as specialchars from (
    select replace(dbo.[SpecialCharacters](bookname), ' ', '') as specialchars           
    from books
)t
for xml path, type).value('.[1]', 'nvarchar(max)'), 1, 0, '');

结果

+--------------+
| specialchars |
+--------------+
| $()#$%^&     |
+--------------+

【讨论】:

    【解决方案2】:

    你可以通过while loop.来做到这一点

    SET NOCOUNT ON
    DECLARE @loop INT
    DECLARE @str VARCHAR(8000), @output VARCHAR(8000)
    SELECT @str = 'ab123ce23,4f$e', @output=''
    SET @loop = 1
    WHILE @loop < LEN(@str)
    BEGIN
    SET @output=@output+CASE WHEN ASCII(SUBSTRING(@str,@loop,1)) BETWEEN 48 AND 57 THEN SUBSTRING(@str,@loop,1) ELSE '' END
    SET @loop = @loop + 1
    END
    SELECT @output
    

    礼貌:pinal 戴夫,http://blog.sqlauthority.com

    请在下面找到相同的链接

    http://blog.sqlauthority.com/2015/08/29/sql-server-remove-all-characters-from-a-string-using-t-sql/

    【讨论】:

    • 哇,这么多人比我聪明:) 好方法!我也会尝试这个解决方案
    • 这不是我的解决方案。我在上面的博客中找到了它。顺便说一句,您可以投票并标记您得到的最佳解决方案。这将有助于其他有相同要求的人
    • 我认为这是一个非常干净的解决方案。我会将其标记为答案。谢谢你和 pinal 戴夫
    【解决方案3】:

    我建议构建 regexp-match + regexp-replace CLR 函数,但您也可以尝试这种老式方法:

    ;with list as
    (
      select 'Alice#wndlnd' as name
      union all
      select 'asdf?!@zz'
      union all
      select 'Regular'
      union all
      select 'last$'
    ),
    list_cleared as
    (
      select 
        replace(
          replace(
            replace(
              replace(
                replace(
                  replace(
                    replace(
                      replace(
                        replace(
                          replace(
                            replace(
                              replace(
                                replace(
                                  replace(
                                    replace(
                                      replace(
                                        replace(
                                          replace(
                                            replace(
                                              replace(
                                                replace(
                                                  replace(
                                                    replace(
                                                      replace(
                                                        replace(
                                                          replace(name
                                                            , 'a', '')
                                                          , 'b', '')
                                                        ,'c', '')
                                                      , 'd', '')
                                                    , 'e', '')
                                                  ,'f', '')
                                                , 'g', '')
                                              , 'h', '')
                                            ,'i', '')
                                          , 'j', '')
                                        , 'k', '')
                                      ,'l', '')
                                    ,'m', '')
                                  , 'n', '')
                                , 'o', '')
                              ,'p', '')
                            , 'q', '')
                          , 'r', '')
                        ,'s', '')
                      ,'t', '')
                    , 'u', '')
                  , 'v', '')
                ,'w', '')
              , 'x', '')
            , 'y', '')
          ,'z', '') as spec_chars
      from list
    )
    select 
      (
        select l.spec_chars
        from list_cleared l
        where l.spec_chars <> ''
        for xml path(''), type
      ).value('.', 'varchar(max)') as spec_chars
    

    【讨论】:

    • 天哪!这是一个很大的查询,但我会检查它是否有效:)
    • 真的好用!谢谢!所以我只是添加字符和替换函数来添加大写字母?
    • 大多数数据库实例和 varchar 列不区分大小写,但如果您的是区分大小写的,则可以添加其他字母或简单地制作 lower(name_column)
    猜你喜欢
    • 2017-06-06
    • 2016-07-08
    • 2018-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-08
    相关资源
    最近更新 更多