3

私はそのような文字列を持っています

テスト 1|ニューヨーク| X、テスト 2| シカゴ|Y、テスト 3| ハリスバーグ、PA| Z

私の必要な結果は

 Column1  Column 2     Column3
 Test 1   new york        X
 Test 2   chicago         Y
 Test 3   harrisburg,pa   Z

しかし、このクエリを実行する

SELECT  
split_part(stat.st, '|', 1) Column1,
split_part(stat.st, '|', 2) Column2,    
split_part(stat.st, '|', 3) Column3
FROM
(
    SELECT
            UNNEST (
                string_to_array('Test 1|new york| X, Test 2| chicago|Y, Test 3| harrisburg, pa| Z',',')
            )
         AS st
) stat;

結果は

 Column1  Column 2   Column3
 Test 1   new york      X
 Test 2   chicago       Y
 Test 3   harrisburg    
 pa          Z  

Column3 はすべての可能性があります ( | を除く)。一致する可能性のあるパターン。これは N 回繰り返すことができます。STRING は | を除くすべての可能性があります。文字。

regexp_split_to_array()希望の結果を設定するにはどうすればよいですか?

4

1 に答える 1

4

これを機能させるのに十分な情報はほとんどありません。しかし、これは仕事をします:

SELECT * FROM crosstab3(
   $$
   SELECT (rn/3)::text AS x, (rn%3)::text, item
   FROM  (
      SELECT row_number() OVER () - 1 AS rn, trim(item) AS item
      FROM (
         SELECT CASE WHEN rn%2 = 1 THEN regexp_split_to_table(item, ',') 
                     ELSE item END AS item
         FROM  (
            SELECT row_number() OVER () AS rn, *
            FROM regexp_split_to_table('Test 1|new york| X, Test 2| chicago|Y, Test 3| harrisburg, pa| Z', '\|') AS item
            ) x
         ) y
      ) z
   $$)

戻り値:

 row_name | category_1 |   category_2   | category_3
----------+------------+----------------+------------
 0        | Test 1     | new york       | X
 1        | Test 2     | chicago        | Y
 2        | Test 3     | harrisburg, pa | Z

で文字列を分割した後、行番号が奇数の行のみを で分割|するという基準に基づいています。 クロス集計を行う前に、結果を取得し、別の導関数を追加して、この中間状態に到達します。,
trim()row_number()

 x | text |      item
---+------+----------------
 0 | 0    | Test 1
 0 | 1    | new york
 0 | 2    | X
 1 | 0    | Test 2
 1 | 1    | chicago
 1 | 2    | Y
 2 | 0    | Test 3
 2 | 1    | harrisburg, pa
 2 | 2    | Z

最後にcrosstab3()、モジュールから関数を適用しtablefuncます。まだインストールしていない場合は、次の手順でインストールします。

CREATE EXTENSION tablefunc;

で前処理regexp_replace()

これは、理解しやすい代替案です。どちらが速いかはわかりません。複雑な正規表現はコストが高くなる傾向があります。

SELECT trim(split_part(a,'|', 1)) AS column1
      ,trim(split_part(a,'|', 2)) AS column2
      ,trim(split_part(a,'|', 3)) AS column3
FROM  (
   SELECT unnest(
             string_to_array(
                         regexp_replace('Test 1|new york| X, Test 2| chicago|Y, Test 3| harrisburg, pa| Z'
                        ,'([^|]*\|[^|]*\|[^,]*),', '\1~^~', 'g'), '~^~')) AS a
   ) sub

これは、続行する前に、,2 つのパイプ ( ) の後でのみコンマ ( ) を置き換えます。パイプ間の空の文字列を許可する代わりに 使用するようになりました。|
*+

于 2013-03-27T17:07:59.883 に答える