使用PostgreSQL-9.1和PostGIS 2.0.1,在进行包含返回多列的子查询的SELECT查询时,我收到错误subquery must return only one column
。
如何修改查询/子查询以返回多个列?
查询
SELECT l.id, l.lat, l.lng, l.geom,
(SELECT g.id, g.lat, g.lng, ST_Distance(l.geom, g.geom)
FROM stage.dogs as g
LIMIT 1)
FROM stage.users As l
完整查询
SELECT l.id, l.lat, l.lng, l.geom,
g.id, g.lat, g.lng, ST_Distance(l.geom, g.geom)
FROM stage.users As l
CROSS JOIN (SELECT *
FROM stage.dogs as g
ORDER BY g.geom <-> l.geom
LIMIT 1) as g
错误
ERROR: invalid reference to FROM-clause entry for table "l"
SQL state: 42P01
Hint: There is an entry for table "l", but it cannot be referenced from this part of the query.
答案 0 :(得分:2)
SELECT l.id, l.lat, l.lng, l.geom,
g.id, g.lat, g.lng, ST_Distance(l.geom, g.geom)
FROM stage.users As l
CROSS JOIN (SELECT * FROM stage.dogs LIMIT 1) as g
这就是你所拥有的(假设stage.dogs)不是空的。不确定users
和dogs
之间是否应该存在关联。
要查找与用户最近的狗,您可以使用此查询。标量子查询找到狗的ID,并连接回表以检索其他列。
SELECT l.id, l.lat, l.lng, l.geom,
g.id, g.lat, g.lng, ST_Distance(l.geom, g.geom)
FROM (
SELECT l1.*, (SELECT g1.id
FROM stage.dogs as g
ORDER BY g.geom <-> l.geom
LIMIT 1) g_id
FROM stage.users As l1
) l
JOIN stage.dogs as g ON g.id = l.g_id;
公平警告,这不是一个快速查询。
冒着执行速度更慢的风险,请参阅下面的查询以查看多个表
SELECT l.id, l.lat, l.lng, l.geom,
g.id, g.lat, g.lng, ST_Distance(l.geom, g.geom) dog_distance,
c.id, c.lat, c.lng, ST_Distance(l.geom, c.geom) cat_distance,
b.id, b.lat, b.lng, ST_Distance(l.geom, b.geom) bird_distance
FROM (
SELECT l1.*, (SELECT g1.id
FROM stage.dogs as g1
ORDER BY g1.geom <-> l.geom
LIMIT 1) dog_id,
(SELECT c1.id
FROM stage.cats as c1
ORDER BY c1.geom <-> l.geom
LIMIT 1) cat_id,
(SELECT b1.id
FROM stage.cats as b1
ORDER BY b1.geom <-> l.geom
LIMIT 1) bird_id
FROM stage.users As l1
) l
LEFT JOIN stage.dogs as g ON g.id = l.dog_id
LEFT JOIN stage.dogs as c ON c.id = l.cat_id
LEFT JOIN stage.dogs as b ON b.id = l.bird_id;
答案 1 :(得分:2)
这为每位用户提供了一行最近的狗:
SELECT DISTINCT ON (l.id)
l.id, l.lat, l.lng, l.geom
,g.id, g.lat, g.lng, ST_Distance(l.geom, g.geom)
FROM stage.users l
CROSS JOIN stage.dogs g
ORDER BY l.id, (l.geom <-> g.geom)
在此相关答案中有关DISTINCT ON
技术的更多信息:
我想如果g.geom
上有GiST index,那么规划师可能会非常聪明,只能从中选择关闭项目。不确定,没试过。否则,这种CROSS JOIN
将导致O(N²),并且使用更大的表格可能会使性能失控。
我引用了Postgis手册here:
如果其中一个几何是一个常量(不在a中),则只能启动索引 子查询/ CTE)。例如
'SRID=3005;POINT(1011102 450541)'::geometry
代替a.geom
所以你可能在这里运气不好。
根据手册,您可能需要ST_Distance()
订购以获得精确的排序顺序,但您不应该获得最远的顺序。这毫无意义。