1

と呼ばれる文字列フィールドを持つテーブルがありますinfo。このフィールドには、「ドライバー:マットカー:マスタング」のようなドライバーと車に関する情報があります。

次のように、2つの列でクエリを取得する方法はありますか| Matt | Mustang |

何ができるのかわからない、正規表現かも?

4

5 に答える 5

2
WITH tbl(id, info) AS (
   VALUES
    (1::int, 'Driver: Matt Car: Mustang'::text)
   ,(2,      'Driver: Billy Car: Porsche')
   )
SELECT id
      ,split_part(info, ' ', 2) AS driver
      ,split_part(info, ' ', 4) As car
FROM   tbl;

戻り値:

 id | driver  | car
----+---------+---------
  1 | Matt    | Mustang
  2 | Billy   | Porsche

スペースがあり、名前がスペースの右側にある限り、「Driver」と「Car」の代わりにどの文字列を使用しても問題ありません。

于 2012-08-09T13:22:25.190 に答える
1

私が間違っていることを理解していなければ、string_to_array関数を使用して文字列を配列要素に分割し、必要に応じて要素に到達することができます。

詳細については、この投稿を参照してください。「string_to_array()」関数から返される配列のN番目の要素を取得します。

于 2012-08-09T10:39:26.313 に答える
0

あなたが話しているのは、シリアライゼーションと呼ばれる非常に残念な設計パターンです。つまり、意味的に異なる複数のデータを単一の文字列に凝縮します。ほとんどの場合、これは悪い考えであり、ほとんどの場合、データを複数のフィールドまたは複数のテーブルに分割することをお勧めします。シリアル化されたフィールドを使用すると、次のことがわかります。

  • 複数のシリアル化されたサブフィールドをクエリする場合、クエリが非常に遅くなります
  • 同じフィールドの複数の部分を更新するための複雑なクエリ
  • 憂鬱感と絶望感

そのようなデータベースを扱う必要があり、データベースの構造を変更できなかった場合、プログラム コードで多くの面倒な作業を行うことになるでしょう。多くの言語には、SQL よりも優れた (または少なくともより直感的な) 文字列処理ツールがあり、RDBMS を使用することによるパフォーマンス上の利点は、シリアル化を処理する場合、せいぜいわずかです。

ただし、これを SQL で絶対に行う必要がある場合は、次の場所にある Postgres の文字列処理を読む必要があります: http://www.postgresql.org/docs/9.1/static/functions-string.html

おっしゃる通り、ソリューションにはおそらく正規表現が含まれます。その正規表現がどのように見えるかは、解析する必要があるシリアル化されたフィールドの数と、正確にどのように区切られているかによって異なります。あなたの例では、各サブフィールドがスペースのペアとそれらの間のパイプ文字で区切られているように見えます。その場合は、必要に応じてその区切り文字をエスケープできるようにするルールを作成するか、フロントエンドが区切り文字をデータベースに渡すことはありません。

もちろん、フロントエンド アプリをそのように制御できる場合は、シリアル化されたデータに独自のフィールドを与えることができます。

于 2012-08-08T15:04:28.483 に答える
0

あなたの最善の策は、これらの値の 1 つを取得し、見つかったものに基づいて適切な列を含むレコードを返す関数を作成することです。これにより、新しい列 (またはテーブル) を作成する前に、SELECT ステートメントを使用して関数をデバッグできます。INSERTその後、クエリを/SELECTまたはで使用できますUPDATE ... FROM

PostgreSQL 正規表現文字列関数を使用して、関数に plpgsql 言語を使用できます。しかし、perl や python に精通している場合は、それらの言語のいずれかで関数を書きたいと思うかもしれません。

于 2012-08-08T15:52:04.793 に答える
0

これは私がしました:

select split_part(( ケース when
strpos(l.info,'Driver:') >= 1 then substr(l.info,strpos(l.info,'Driver:')+10, strpos(l.info,'Driver:') ')+9) end),E'\n',1) ガレージからのドライバーとして

まったくきれいではありませんが、必要に応じてデータを返します

于 2012-08-09T12:49:18.667 に答える