如何在psql中的更多列中拆分列?

时间:2015-10-20 07:43:43

标签: postgresql split

我想使用另一个列创建一个视图,我有这个专栏:

stack_prices : 1=1.95 | 3=1.89 | 10=1.85

我想制作(例如)6列,如:

stack_size1: 1  stack_price1: 1.95 
stack_size2: 3  stack_price2: 1.89 
stack_size3: 10 stack_price3: 1.85

我尝试过使用子字符串,有点工作,但是这个例子是硬编码的:

substr(cp.stack_prices,3,4) AS company_product_price1,
substr(cp.stack_prices,1,1) AS company_product_stack_size1 etc...

我实际上想要在|=之后拆分。

3 个答案:

答案 0 :(得分:0)

您需要分两个阶段完成:

  1. '|'
  2. 拆分
  3. '='
  4. 拆分

    您可以像这样使用string_to_array

    SELECT
        'stack_size'|| id || ': ' || trim(split2[1]),
        'stack_price'|| id || ': ' || trim(split2[2])
    FROM  (
        SELECT  row_number() OVER() AS id, string_to_array(sub.split1, '=') as split2
        FROM (
           (SELECT unnest(string_to_array(stack_prices, '|')) AS split1 FROM company_product)
        ) sub
    ) sub
    

    编辑:

    当您在问题中写下时,上面的查询输出将是非常明确的。它可以用来只处理一行(例如,你可以把它放在存储过程中)

    如果您希望更通用的解决方案在一行中有6列,那么就有一个:

    SELECT
        stack_prices,
        split1_1[1] as ss1, split1_1[2] as sp1,
        split1_2[1] as ss2, split1_2[2] as sp2,
        split1_3[1] as ss3, split1_3[2] as sp3
    FROM (
        SELECT
            stack_prices,
            regexp_split_to_array(split1[1], E'=') as split1_1,
            regexp_split_to_array(split1[1], E'=') as split1_2,
            regexp_split_to_array(split1[1], E'=') as split1_3
        FROM (
            select
                stack_prices,
                regexp_split_to_array(stack_prices, E'\\ \\|\\ ') as split1 
            from company_product
        ) sub
    ) sub
    

答案 1 :(得分:0)

这很有效。

从company_product cp中选择split_part((split_part(cp.stack_prices,' |',1)),' =',1);     从company_product cp中选择split_part((split_part(cp.stack_prices,' |',1)),' =',2);

从company_product cp中选择split_part((split_part(cp.stack_prices,' |',2)),' =',1);     从company_product cp中选择split_part((split_part(cp.stack_prices,' |',2)),' =',2);

从company_product cp中选择split_part((split_part(cp.stack_prices,' |',3)),' =',1);     从company_product cp中选择split_part((split_part(cp.stack_prices,' |',3)),' =',2);

答案 2 :(得分:0)

丑陋的问题:丑陋的解决方案:

CREATE TABLE stack_prices (
        ugly_string text
        );

INSERT INTO stack_prices ( ugly_string ) VALUES
 ('1=1.95 | 3=1.89 | 10=1.85' );

SELECT ugly_string AS orig
, regexp_replace(ugly_string, ' *([0-9])*=.*', '\1') AS n1
, regexp_replace(ugly_string, ' *[0-9]*=([0-9.]*).*', '\1') AS v1
, regexp_replace(ugly_string, ' *[0-9]*=[0-9.]* \| ([0-9]*)=.*', '\1') AS n2
, regexp_replace(ugly_string, ' *[0-9]*=[0-9.]* \| [0-9]*=([0-9.]*) \|.*', '\1') AS v2
, regexp_replace(ugly_string, ' *[0-9]*=[0-9.]* \| [0-9]*=[0-9.]* \| ([0-9]*).*', '\1') AS n3
, regexp_replace(ugly_string, ' *[0-9]*=[0-9.]* \| [0-9]*=[0-9.]* \| [0-9]*=([0-9.]*).*', '\1') AS v3
FROM stack_prices
        ;

结果:

CREATE TABLE
INSERT 0 1
           orig            | n1 |  v1  | n2 |  v2  | n3 |  v3  
---------------------------+----+------+----+------+----+------
 1=1.95 | 3=1.89 | 10=1.85 | 1  | 1.95 | 3  | 1.89 | 10 | 1.85
(1 row)