如何使用下划线(_)和句点(。)来拆分值?

时间:2016-02-11 03:37:03

标签: mysql sql postgresql

我有一个包含字符串的表:

Orig_Value
-----------
Abc_abc_1.2.3
PQRST.abc_1
XY.143_z

我想使用_.将其与所需的输出分开:

Original_Value    Col1    Col2   Col3   Col4   Col5
-------------     ----    ----   ----   ----   ----
Abc_abc_1.2.3     Abc      abc     1      2     3
PQRST.abc_1       PQRST    abc     1
XY.143_z          XY       143     z

查询MSSql和MySQL或PostgreSQL即可。

我尝试使用类似下面的查询的子字符串函数,但它不适用于我拥有的所有数据:

code

3 个答案:

答案 0 :(得分:2)

<强> PostgreSQL

以下为例,

CREATE TABLE foo (org_val TEXT);

INSERT INTO foo
VALUES ('Abc_abc_1.2.3')
      ,('PQRST.abc_1')
      ,('XY.143_z');

使用regexp_split_to_array()

SELECT org_val
    ,a [1] col1
    ,a [2] col2
    ,a [3] col3
    ,a [4] col4
    ,a [5] col5
FROM (
    SELECT org_val
        ,regexp_split_to_array(replace(org_val, '.', '_'),'_') AS a
    FROM foo
    ) t

结果:

org_val       col1  col2 col3 col4 col5 
------------- ----- ---- ---- ---- ---- 
Abc_abc_1.2.3 Abc   abc  1    2    3    
PQRST.abc_1   PQRST abc  1    NULL NULL 
XY.143_z      XY    143  z    NULL NULL 

SQLFIDDLE-DEMO

答案 1 :(得分:1)

以下是SQL Server

中的一种方法
;WITH cte
     AS (SELECT Replace(col, '_', '.') + '.' AS col
         FROM   (VALUES ('Abc_abc_1.2.3'),
                        ('PQRST.abc_1'),
                        ('XY.143_z')) tc (col))
SELECT original_col = col,
       column_1=COALESCE(LEFT(col, Charindex('.', col) - 1), ''),
       column_2=COALESCE(Substring(col, P1.POS + 1, P2.POS - P1.POS - 1), ''),
       column_3=COALESCE(Substring(col, P2.POS + 1, P3.POS - P2.POS - 1), ''),
       column_4=COALESCE(Substring(col, P3.POS + 1, P4.POS - P3.POS - 1), ''),
       column_4=COALESCE(Substring(col, P4.POS + 1, P5.POS - P4.POS - 1), '')
FROM   cte
       CROSS APPLY (VALUES (CASE
                     WHEN Charindex('.', col) >= 1 THEN Charindex('.', col)
                   END)) AS P1(POS)
       CROSS APPLY (VALUES (CASE
                     WHEN Charindex('.', col, P1.POS + 1) >= 1 THEN Charindex('.', col, P1.POS + 1)
                   END)) AS P2(POS)
       CROSS APPLY (VALUES (CASE
                     WHEN Charindex('.', col, P2.POS + 1) >= 1 THEN Charindex('.', col, P2.POS + 1)
                   END )) AS P3(POS)
       CROSS APPLY (VALUES (CASE
                     WHEN Charindex('.', col, P3.POS + 1) >= 1 THEN Charindex('.', col, P3.POS + 1)
                   END)) AS P4(POS)
       CROSS APPLY (VALUES (CASE
                     WHEN Charindex('.', col, P4.POS + 1) >= 1 THEN Charindex('.', col, P4.POS + 1)
                   END)) AS P5(POS) 

<强>结果:

╔════════════════╦══════════╦══════════╦══════════╦══════════╦══════════╗
║  original_col  ║ column_1 ║ column_2 ║ column_3 ║ column_4 ║ column_4 ║
╠════════════════╬══════════╬══════════╬══════════╬══════════╬══════════╣
║ Abc.abc.1.2.3. ║ Abc      ║ abc      ║ 1        ║        2 ║        3 ║
║ PQRST.abc.1.   ║ PQRST    ║ abc      ║ 1        ║          ║          ║
║ XY.143.z.      ║ XY       ║ 143      ║ z        ║          ║          ║
╚════════════════╩══════════╩══════════╩══════════╩══════════╩══════════╝

答案 2 :(得分:1)

使用基本功能translate() and split_part() Postgres 简单快捷:

AbstractAjaxTimerBehavior

完全符合要求的结果 SQL Fiddle.

在另一个答案中广告的正则表达式函数功能强大但价格昂贵。这应该快得多。比较: