首页 > 解决方案 > 使用 REGEXP_EXTRACT 收集数据

问题描述

P2_PCM_C_L112_2011_00_1v
P2_PCM_L212_2012_00_1v
P2_PCM_L119_2011_00_1v
P2_ABB_C_L6712_2012_00_1v
P2_PCM_L17612_2014_00_1v

我想收集 PCM 或 ABB 等信息,然后使用 REGXP_EXTRACT 从上面的 2011 年收集信息,你能建议一下代码吗

标签: sql-server

解决方案


请尝试以下解决方案。

它基于 XQuery。它允许我们在不使用 REGEX 的情况下对输入字符串进行标记。

甚至令牌的动态结构也不是问题:

  • 代码(PCM 或 ABB)是第二个令牌。
  • 年份位置是动态的(4 或 5),但它始终是右侧第三个标记。

WHERE最后,我们有一个关系/矩形结果集,因此我们可以通过子句轻松查询/过滤它。

SQL

-- DDL and sample data population, start
DECLARE @tbl TABLE (tokens VARCHAR(8000));
INSERT INTO @tbl (tokens) VALUES
('P2_PCM_C_L112_2011_00_1v'),
('P2_PCM_L212_2012_00_1v'),
('P2_PCM_L119_2011_00_1v'),
('P2_ABB_C_L6712_2012_00_1v'),
('P2_PCM_L17612_2014_00_1v');
-- DDL and sample data population, end

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

WITH rs AS
(
    SELECT *
        , code = c.value('(/root/r[2]/text())[1]', 'CHAR(3)') 
        , token_year = c.value('(/root/r[last() - 2]/text())[1]', 'INT') 
    FROM @tbl
       CROSS APPLY (SELECT TRY_CAST('<root><r><![CDATA[' + 
          REPLACE(tokens, @separator, ']]></r><r><![CDATA[') + 
          ']]></r></root>' AS XML)) AS t(c)
)
SELECT * FROM rs
--WHERE code = ... AND token_year = ...;

输出

+----+---------------------------+------+------------+
| ID |          tokens           | code | token_year |
+----+---------------------------+------+------------+
|  1 | P2_PCM_C_L112_2011_00_1v  | PCM  |       2011 |
|  2 | P2_PCM_L212_2012_00_1v    | PCM  |       2012 |
|  3 | P2_PCM_L119_2011_00_1v    | PCM  |       2011 |
|  4 | P2_ABB_C_L6712_2012_00_1v | ABB  |       2012 |
|  5 | P2_PCM_L17612_2014_00_1v  | PCM  |       2014 |
+----+---------------------------+------+------------+

推荐阅读