【问题标题】:SQL Server 2016: Numbers Wildcard [^0-9] - filter out 0000SQL Server 2016:数字通配符 [^0-9] - 过滤掉 0000
【发布时间】:2017-10-17 13:06:39
【问题描述】:

我对 4 字符字段使用通配符来过滤掉非数字值,这可以正常工作,但是我也想过滤掉“0000”值。是否可以不使用'AND/OR'

DECLARE @D VARCHAR(4) = '0000'

SELECT  
    (CASE
        WHEN @D NOT LIKE '%[^0-9]%' 
           THEN CONVERT(INT, LEFT(@D, 2))
           ELSE NULL 
     END)

【问题讨论】:

  • 标记您正在使用的 dbms。该代码是特定于产品的。

标签: sql sql-server tsql case sql-server-2016


【解决方案1】:

使用AND 添加额外参数。

DECLARE @D VARCHAR(4) = '0000'

SELECT (CASE WHEN @D NOT LIKE '%[^0-9]%' AND @D != '0000' 
         THEN CONVERT(INT, LEFT(@D, 2))
         ELSE NULL END)

工作示例。

SELECT CASE WHEN yourfield NOT LIKE '%[^0-9]%' AND yourfield != '0000' 
       THEN 'xxx'
       ELSE NULL END
FROM yourtable

输入

1234
abcd
ab12
0000
9999

输出

xxx
(null)
(null)
(null)
xxx

SQL 小提琴:http://sqlfiddle.com/#!6/4b0e4/1/0

不需要AND/OR

SELECT yourfield, 
CASE WHEN 0 = PATINDEX('%[^0-9]%', REPLACE(yourfield,'0000','aaaa'))
     THEN 'xxx'
     ELSE NULL 
END AS filtered
FROM yourtable

输出

yourfield filtered
1234      xxx
abcd      (null)
ab12      (null)
0000      (null)
9999      xxx

SQL 小提琴:http://sqlfiddle.com/#!6/4b0e4/45/0

【讨论】:

  • 感谢您的回答。我希望找到一个通配符/正则表达式解决方案,而不必使用AND/OR
  • @Tsar 添加了不需要AND/OR 的附加答案。
  • 有趣的是执行计划是一样的,我应该选择哪一个?
  • @Tsar 数据集有多大?
  • 500K 行,此检查每行执行两次 - 选择 LEFT(@D, 2) & RIGHT(@D, 2)
【解决方案2】:

您根本不需要LIKECASE

DECLARE @D VARCHAR(4) = '0000';
SELECT LEFT(TRY_CAST(NULLIF(@D, '0000') AS INT),2)+0;

Rextester Demo


编辑:

SELECT s.d,LEFT(TRY_CAST(NULLIF(s.d, '0000') AS INT),2)+0
FROM (SELECT '0000' UNION SELECT '12ab' UNION SELECT '1234') s(d);

Rextester Demo2

输出:

0000    NULL
1234    12
12ab    NULL

【讨论】:

    【解决方案3】:

    这将为 '0000' 输出 NULL:

    DECLARE @D VARCHAR(4) = '0000'
    
    SELECT  (CASE WHEN @D NOT LIKE '%[^0-9]%'
                 THEN CONVERT(INT, LEFT(NULLIF(@D, '0000'), 2))
                 ELSE NULL
             END)
    

    【讨论】:

      【解决方案4】:

      需要注意的几点: 1. ELSE NULL 在 CASE 语句中是多余的; NULL 是默认值 2. 如果只返回两个正数,则不需要 int; tinyint 就可以了。

      还有其他几种方法:

      技巧1

      DECLARE @D VARCHAR(4) = '1x234'
      
      SELECT
        CASE 
          WHEN PATINDEX('%[^0-9]%',@D)+CHARINDEX('0000',@D)=0 
              THEN CONVERT(tinyint, LEFT(@D, 2)) 
        END
      

      技巧2

      SELECT MAX(CONVERT(tinyint, LEFT(@D, 2)))
      WHERE PATINDEX('%[^0-9]%',@D)+CHARINDEX('0000',@D) = 0
      

      【讨论】:

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