Select 使用正则表达式匹配的字符串的特定部分

Select specific portion of string using Regex match

请考虑以下 table。我试图仅检索 Tax 字符串中的欧元金额。一些记录的大小差异较大,但浮点数始终存在。

OrderID    SKU      Price    Tax
****       ****     ****     [<TV<standard#21.0#false#21.36#EUR>VT>]
****       ****     ****     [<TV<standard#21.0#false#7.21#EUR>VT>]
****       ****     ****     [<TV<standard#17.0#false#5.17#EUR>VT>]

我写了一个匹配我需要的正则表达式:\d+\W\d+ returns 我在字符串中有两个浮点值。在 Oracle SQL 中,我可以通过如下查询简单地获得第二次出现:

SELECT REGEXP_SUBSTR(column, '\d+\W\d+',1,2) FROM table

使用上述方法,我检索了这三个记录的 21.367.215.17

如何使用 SQL 服务器实现此目的?

显然正则表达式可能是此处的首选工具。但是 SQL 服务器没有太多的本地正则表达式支持。这是一个使用 PATINDEXCHARINDEX 的纯 SQL 服务器解决方案。它有点冗长,但可以完成工作:

SELECT
    SUBSTRING(Tax,
              CHARINDEX('#', Tax, PATINDEX('%[0-9]#%', Tax) + 3) + 1,
              CHARINDEX('#', Tax, CHARINDEX('#', Tax, PATINDEX('%[0-9]#%', Tax) + 3) + 1) -
              CHARINDEX('#', Tax, PATINDEX('%[0-9]#%', Tax) + 3) - 1)
FROM yourTable;

Demo

请尝试以下解决方案。

该方法使用 XML 对税收列进行标记化。 它为每一行生成如下所示的 XML:

<root>
  <r>[&lt;TV&lt;standard</r>
  <r>21.0</r>
  <r>false</r>
  <r>21.36</r>
  <r>EUR&gt;VT&gt;]</r>
</root>

第 4 个 r 元素是有问题的货币价值。

SQL

-- DDL and sample data population, start
DECLARE @tbl TABLE (ID INT IDENTITY PRIMARY KEY, Tax VARCHAR(MAX));
INSERT INTO @tbl (Tax) VALUES
('[<TV<standard#21.0#false#21.36#EUR>VT>]'),
('[<TV<standard#21.0#false#7.21#EUR>VT>]'),
('[<TV<standard#17.0#false#5.17#EUR>VT>]');
-- DDL and sample data population, end

DECLARE @separator CHAR(1) = '#';

SELECT t.*
    , c.value('(/root/r[4]/text())[1]', 'DECIMAL(10,2)') AS result
FROM @tbl AS t
CROSS APPLY (SELECT TRY_CAST('<root><r><![CDATA[' + 
        REPLACE(tax, @separator, ']]></r><r><![CDATA[') + 
        ']]></r></root>' AS XML)) AS t1(c);

输出

+----+-----------------------------------------+--------+
| ID |                   Tax                   | result |
+----+-----------------------------------------+--------+
|  1 | [<TV<standard#21.0#false#21.36#EUR>VT>] |  21.36 |
|  2 | [<TV<standard#21.0#false#7.21#EUR>VT>]  |   7.21 |
|  3 | [<TV<standard#17.0#false#5.17#EUR>VT>]  |   5.17 |
+----+-----------------------------------------+--------+