如何从SQL中的字符串解析数字

时间:2016-05-19 10:33:25

标签: sql sql-server-2012

我有一个带有产品名称列的表,其中包含产品编号。产品名称不具有从中提取产品编号的独特风格。以下是产品名称预期产品编号的一些示例:

产品名称和产品编号

Cranfield 29-7                   -->   29-7 
LCFU  23-3  ( MAYE S BUSHY UNIT) -->   23-3
CORE TEST         D              -->   D
BFU 33-8  (ROBERT H BOLING)   1  -->   1
Gwinville 14-12     3            -->   3  

因此,我的产品名称不是唯一的样式,如果您观察,则没有固定的分隔符。我需要一个获取产品名称并返回产品编号的功能。 请记住,varchar数据类型的产品名称和产品编号。产品编号可以是基于产品名称的字母,数字或字母数字。

如果任何身体也告诉逻辑,我将不胜感激。

2 个答案:

答案 0 :(得分:2)

如果没有算法,则无法构建查询。

只有在知道字符串格式时才能构建算法。

但是,您似乎不知道格式,只知道示例。这些例子的工作算法是:

  1. 从右边删除空格(如果有的话)
  2. 从右侧删除括号中的文字(如果有的话)
  3. 从右边删除空格(如果有的话)
  4. 从右边提取字符串,直到你打空白
  5. 虽然这适用于您的示例,但绝不保证您可以使用数据库中的任何字符串。

答案 1 :(得分:2)

这是一种让所有部分整齐分离的方法。您可以找到一些逻辑来解释这一点。

this致于摆脱多个空白的方法。

编辑:添加了一些替换,以允许像&,>这样的字符。和<

DECLARE @tbl TABLE(ID INT,Test VARCHAR(MAX));
INSERT INTO @tbl VALUES
 (1,'Cranfield 29-7')
,(2,'LCFU  23-3       ( MAYE S BUSHY UNIT)')
,(3,'BFU 33-8  (ROBERT H BOLING)         1')
,(4,'Gwinville 14-12     3')
,(5,'Procter&Gamble 14-12     3')
,(6,'This->works 14-12     3')
;

WITH Splitted(ID,AsXml) AS
(
    SELECT ID
          ,CAST('<x>'+ REPLACE(REPLACE(REPLACE(
           REPLACE(
              REPLACE(
                 REPLACE(
                    LTRIM(RTRIM(REPLACE(REPLACE(REPLACE(Test,'&','&amp;'),'<','&lt;'),'>','&gt;'))), 
                 '  ',' |'),                 
              '| ',''),                        
           '|',''),'(','<paran><x>'),')','</x></paran>'),' ','</x><x>') + '</x>' AS XML)
    FROM @tbl
)
SELECT p.*
FROM
(
    SELECT ID
          ,'part_' + CAST(ROW_NUMBER() OVER(PARTITION BY ID ORDER BY (SELECT NULL)) AS VARCHAR(10)) AS colName
          ,A.B.value('.','nvarchar(max)') AS Part
    FROM Splitted
    CROSS APPLY AsXml.nodes('/x') AS A(B)
) AS tbl
PIVOT
(
    MIN(Part) FOR colName IN(part_1,part_2,part_3,part_4,part_5,part_6)
) AS p

结果

+----+----------------+--------+----------------+--------+--------+--------+
| ID | part_1         | part_2 | part_3         | part_4 | part_5 | part_6 |
+----+----------------+--------+----------------+--------+--------+--------+
| 1  | Cranfield      | 29-7   | NULL           | NULL   | NULL   | NULL   |
+----+----------------+--------+----------------+--------+--------+--------+
| 2  | LCFU           | 23-3   | MAYESBUSHYUNIT | NULL   | NULL   | NULL   |
+----+----------------+--------+----------------+--------+--------+--------+
| 3  | BFU            | 33-8   | ROBERTHBOLING  | 1      | NULL   | NULL   |
+----+----------------+--------+----------------+--------+--------+--------+
| 4  | Gwinville      | 14-12  | 3              | NULL   | NULL   | NULL   |
+----+----------------+--------+----------------+--------+--------+--------+
| 5  | Procter&Gamble | 14-12  | 3              | NULL   | NULL   | NULL   |
+----+----------------+--------+----------------+--------+--------+--------+
| 6  | This->works    | 14-12  | 3              | NULL   | NULL   | NULL   |
+----+----------------+--------+----------------+--------+--------+--------+