2

int の配列を含むテーブルがあります (これを lineTable と呼びます)。その int の配列は、別のテーブル (pointTable) 内の一意の ID の配列を表します。ポイント テーブルには、3 つの列 (id、x、y) が含まれています。

lineTable.points 内のこれらの各 int を int の配列の配列に変換できるようにしたいと考えています。

lineTable              pointTable
| id | points |        | id | x | y |
| int| int[]  |        | int|int|int|

lineTable
| 1 | {1, 2, 3, 4, 5} |
| 2 | {4, 7, 5, 2, 3} |
| 3 | {8, 1}          |
etc

pointTable
| 1 | 1 | 0 |
| 2 | 2 | 1 |
| 3 | 5 | 6 |
| 4 | 7 | 0 |
| 5 | 2 | 4 |
| 6 | 5 | 2 |
| 7 | 4 | 4 |
| 8 | 5 | 9 |

したがって、最終的な出力は次のようになります

lineValues
| {{1, 0}, {2, 1}, {5, 6}, {7, 0}, {2, 4}} |
| {{7, 0}, {4, 4}, {2, 4}, {2, 1}, {5, 6}} |
| {{5, 9}, {1, 0}}                         |

注: ID は任意の番号にすることができ、連続したパターンではありません (1、2、5、10、11、18 になる場合があります)。

Postgre 9.2 を使用しています。

ご協力ありがとうございます。他の情報が必要/欲しい場合はお知らせください。

4

1 に答える 1

1

配列でネイティブの Point 型などの複合型を使用する場合、これは非常に簡単です。このようなもの:

select dt.id, array_agg(point(p.x, p.y))
from pointtable p
join (
    select id, unnest(points) as p
    from linetable
) as dt on p.id = dt.p
group by dt.id
order by dt.id;

次のような出力が得られます。

 id |                 array_agg                 
----+-------------------------------------------
  1 | {"(1,0)","(2,1)","(5,6)","(7,0)","(2,4)"}
  2 | {"(2,4)","(4,4)","(7,0)","(5,6)","(2,1)"}
  3 | {"(1,0)","(5,9)"}

その後、ポイントを操作できます。

本当に 2 次元配列が必要な場合は、独自の集計関数を作成できます

create aggregate
array_cat_agg(int[])
(sfunc = array_cat, stype = int[], initcond = '{}');

その後:

select dt.id, array_cat_agg(array[[p.x, p.y]])
from pointtable p
join (
    select id, unnest(points) as p
    from linetable
) as dt on p.id = dt.p
group by dt.id
order by dt.id;

これを取得するには:

 id |          array_cat_agg          
----+---------------------------------
  1 | {{1,0},{2,1},{5,6},{7,0},{2,4}}
  2 | {{2,1},{5,6},{7,0},{2,4},{4,4}}
  3 | {{1,0},{5,9}}

トリッキーに注意してくださいarray[[...]]。正しいバージョンの を確実に取得するために必要ですarray_catarray[...]そうすると、フラット化された配列になってしまい、悲しくなります。array_agg配列の配列のようなものはなく、配列の配列array_agg(array[p.x, p.y])を作成したいので、ここで使用することはできません。したがって、カスタム集計です。

于 2012-11-16T23:40:53.717 に答える