2016-02-11 2 views
2

У меня есть таблица со строками:Как разделить значение с помощью подчеркивания (_) и периода (.)?

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

+4

Вы должны показать, что вы пробовали до сих пор –

+0

Похоже, плохой дизайн схемы, где несколько полей пытаются сосуществовать в одной и той же колонке. –

+2

Также: размещение изображений кода и данных вместо текста для кода и данных считается очень грубым здесь. Это затрудняет нам помощь. –

ответ

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  ║   ║   ║ 
╚════════════════╩══════════╩══════════╩══════════╩══════════╩══════════╝ 
+0

Вау! Я также попытался использовать его, и он работал Спасибо большое!: D – fLen

2

PostgreSQL

Вслед как exampple,

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

Я пробовал это в postgreSQL, и это сработало! спасибо! – fLen

1

Простой и быстрый в Postgres с использованием основных функций translate() and split_part():

SELECT t.* 
    , split_part(o, '.', 1) AS col1 
    , split_part(o, '.', 2) AS col2 
    , split_part(o, '.', 3) AS col3 
    , split_part(o, '.', 4) AS col4 
    , split_part(o, '.', 5) AS col5 
FROM tbl t, translate(t.orig_val, '_', '.') o; -- implicit LATERAL join 

Результат точно так, как хотелось бы.
SQL Fiddle.

Функции регулярного выражения, как рекламируемые в другом ответе, являются мощными, но дорогими. Это должно быть значительно быстрее. Сравните: