【问题标题】:SQL Query to parse numbers from nameSQL 查询从名称中解析数字
【发布时间】:2015-05-30 11:45:18
【问题描述】:

本例中的 DBMS 是 SQL Server 2012。

我需要一个仅从设备名称中获取数字的 SQL 查询。我的设备遵循应该如下所示的命名方案:

XXXnnnnn

XXXnnnnn-XX

其中 X 是一个字母,n 是一个数字,应该在适当的地方用 0 填充。但是,并非所有名称都以这种方式正确填充。

所以,假设您有一个看起来像这样的列:

    Name
    ----
    XXX01234
    XXX222
    XXX0390-A2
    XXX00965-A1

我需要一个 SQL 查询,该查询将从此示例列返回结果,如下所示。

    Number
    ------
    01234
    00222
    00390
    00965

有人有什么想法吗?我尝试过先将名称转换为浮点数,然后再转换为整数,但老实说,我对 SQL 的熟练程度还不够,无法找到解决方案。

非常感谢任何帮助!

【问题讨论】:

  • 使用的 DBMS 是什么?
  • 对不起,我真的应该在帖子中包含它,不是吗?它是 MSSQL。我将编辑帖子以反映这一点。

标签: sql sql-server casting


【解决方案1】:

SQL Server 没有很好的字符串解析功能。对于您的特定示例,我认为 case 语句可能是最简单的方法:

select (case when number like '___[0-9][0-9][0-9][0-9][0-9]%'
             then substring(number, 4, 5)
             when number like '___[0-9][0-9][0-9][0-9]%'
             then '0' + substring(number, 4, 4)
             when number like '___[0-9][0-9][0-9]%'
             then '00' + substring(number, 4)
             when number like '___[0-9][0-9]%'
             then '000' + substring(number, 4, 2)
             when number like '___[0-9][0-9]%'
             then '0000' + substring(number, 4, 1)
             else '00000'
        end) as EmbeddedNumber

【讨论】:

    【解决方案2】:

    这可能有效:

    SELECT RIGHT('00000'
                 + SUBSTRING(Col, 1, ISNULL(NULLIF((PATINDEX('%-%', Col)), 0) - 1, LEN(Col))), 5)
    FROM   (SELECT REPLACE(YourColumn, 'XXX', '') Col
            FROM   YourTable)t 
    

    SQLFIDDLE

    【讨论】:

      【解决方案3】:

      即使 XXX 可以是不同的 len,这也可以工作:

      DECLARE @t TABLE ( n NVARCHAR(50) )
      
      INSERT  INTO @t
      VALUES  ( 'XXXXXXX01234' ),
              ( 'XX222' ),
              ( 'X0390-A2' ),
              ( 'XXXXXXX00965-A1' )
      
      SELECT  REPLICATE('0', 5 - LEN(n)) + n AS n
      FROM    ( SELECT    SUBSTRING(n, PATINDEX('%[0-9]%', n),
                                    CHARINDEX('-', n + '-') - PATINDEX('%[0-9]%', n)) AS n
                FROM      @t
              ) t
      

      输出:

      n
      01234
      00222
      00390
      00965
      

      【讨论】:

      • 作者提到他有XXXnnnnn或XXXnnnnn-XX
      【解决方案4】:

      如果总是需要删除前 3 个字符,那么您可以执行类似的操作(如果字符仅在 '-' 符号之后开始,则将起作用):

      DECLARE @a AS TABLE ( a VARCHAR(100) );
      
      INSERT  INTO @a
      VALUES
              ( 'XXX01234' ),
              ( 'XXX222' ),
              ( 'XXX0390-A2' ),
              ( 'XXX00965-A1' );
      
      SELECT RIGHT('00000' + SUBSTRING(a, 4, CHARINDEX('-',a+'-')-4),5)
      FROM  @a
      -- OUTPUT
      01234
      00222
      00390
      00965
      

      另一个选项(将提取前 3 个字符后的数字):

      SELECT
          RIGHT('00000' + LEFT(REPLACE(a, LEFT(a, 3), ''),
                               COALESCE(NULLIF(PATINDEX('%[^0-9]%',
                                                        REPLACE(a, LEFT(a, 3), '')),
                                               0) - 1,
                                        LEN(REPLACE(a, LEFT(a, 3), '')))), 5)
      FROM
          @a;
      
          -- OUTPUT
          01234
          00222
          00390
          00965
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-27
        • 1970-01-01
        • 2015-01-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多