2

我有一个包含整数数组的表(我们称之为 lineTable)。该 int 数组表示另一个表 (pointTable) 中的唯一 id 数组。点表又包含 3 列(id、x、y)。

我希望能够将 lineTable.points 中的每一个整数转换为整数数组的数组。

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)"}

然后你可以处理这些点。

如果你真的想要一个二维数组,那么你可以创建自己的聚合函数

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_cat,如果您只是array[...]这样,您最终会得到一个扁平的数组,这会让您感到难过。您不能只array_agg在此处使用,因为没有数组数组之类的东西,并且array_agg(array[p.x, p.y])想要创建数组数组。因此自定义聚合。

于 2012-11-16T23:40:53.717 回答