と呼ばれる文字列フィールドを持つテーブルがありますinfo
。このフィールドには、「ドライバー:マットカー:マスタング」のようなドライバーと車に関する情報があります。
次のように、2つの列でクエリを取得する方法はありますか| Matt | Mustang |
。
何ができるのかわからない、正規表現かも?
と呼ばれる文字列フィールドを持つテーブルがありますinfo
。このフィールドには、「ドライバー:マットカー:マスタング」のようなドライバーと車に関する情報があります。
次のように、2つの列でクエリを取得する方法はありますか| Matt | Mustang |
。
何ができるのかわからない、正規表現かも?
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」の代わりにどの文字列を使用しても問題ありません。
私が間違っていることを理解していなければ、string_to_array
関数を使用して文字列を配列要素に分割し、必要に応じて要素に到達することができます。
詳細については、この投稿を参照してください。「string_to_array()」関数から返される配列のN番目の要素を取得します。
あなたが話しているのは、シリアライゼーションと呼ばれる非常に残念な設計パターンです。つまり、意味的に異なる複数のデータを単一の文字列に凝縮します。ほとんどの場合、これは悪い考えであり、ほとんどの場合、データを複数のフィールドまたは複数のテーブルに分割することをお勧めします。シリアル化されたフィールドを使用すると、次のことがわかります。
そのようなデータベースを扱う必要があり、データベースの構造を変更できなかった場合、プログラム コードで多くの面倒な作業を行うことになるでしょう。多くの言語には、SQL よりも優れた (または少なくともより直感的な) 文字列処理ツールがあり、RDBMS を使用することによるパフォーマンス上の利点は、シリアル化を処理する場合、せいぜいわずかです。
ただし、これを SQL で絶対に行う必要がある場合は、次の場所にある Postgres の文字列処理を読む必要があります: http://www.postgresql.org/docs/9.1/static/functions-string.html
おっしゃる通り、ソリューションにはおそらく正規表現が含まれます。その正規表現がどのように見えるかは、解析する必要があるシリアル化されたフィールドの数と、正確にどのように区切られているかによって異なります。あなたの例では、各サブフィールドがスペースのペアとそれらの間のパイプ文字で区切られているように見えます。その場合は、必要に応じてその区切り文字をエスケープできるようにするルールを作成するか、フロントエンドが区切り文字をデータベースに渡すことはありません。
もちろん、フロントエンド アプリをそのように制御できる場合は、シリアル化されたデータに独自のフィールドを与えることができます。
あなたの最善の策は、これらの値の 1 つを取得し、見つかったものに基づいて適切な列を含むレコードを返す関数を作成することです。これにより、新しい列 (またはテーブル) を作成する前に、SELECT ステートメントを使用して関数をデバッグできます。INSERT
その後、クエリを/SELECT
またはで使用できますUPDATE ... FROM
。
PostgreSQL 正規表現文字列関数を使用して、関数に plpgsql 言語を使用できます。しかし、perl や python に精通している場合は、それらの言語のいずれかで関数を書きたいと思うかもしれません。
これは私がしました:
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) ガレージからのドライバーとして
まったくきれいではありませんが、必要に応じてデータを返します