对于每一行,查找之前的任何行是否包含更高的值
For each row, find if any previous rows contains a higher value
我正在尝试使用 PostgreSQL 和 PostGIS 中的 SQL 解决视线 (LoS) 问题。为此,我有一个 table pitch_at_point
,其中包含一个 ID、一个点几何形状和一个间距。
pitch_at_point(id integer,geom geometry,degrees float)
id 列的最低值是视距的起点,最高值是最远的。对于这些点中的每一个,我想确定是否有任何点具有较低的 id,也具有较高的音高(度)。如果是这样的话,那点就看不出来了
我一直在寻找解决方案。我尝试使用递归查询,如下面的 SQL 所示:
WITH RECURSIVE
walk_points AS
(
SELECT ARRAY[id] AS idlist,geom,degrees,id
FROM pitch_at_point
WHERE degrees = (SELECT max(degrees) FROM pitch_at_point)
UNION ALL
SELECT array_append(w.idlist, n.id) AS idlist,n.geom,n.degrees,n.id
FROM pitch_at_point n, walk_points w
WHERE n.degrees < any(SELECT n.degrees FROM pitch_at_point WHERE NOT
w.idlist @> ARRAY[n.id])
)
SELECT * FROM walk_points
我希望得到一个 return 所有点之前有更高音高的点,但我只得到一个点的结果,即使我使用 WHERE n.degrees > any(
。
我很难弄清楚 PostgreSQL 递归 CTE,所以如果有人能帮助我,我将不胜感激。
我可能错了,但这不就是:
select
id, geom, degrees
from pitch_at_point
where exists
(
select *
from pitch_at_point before
where before.id < pitch_at_point.id
and before.degree > pitch_at_point.degree
);
这会获取 ID 较低的记录具有较高音高的所有点。
使用 MAX 的窗口版本可能会更快:
select id, geom, degrees
from
(
select
id, geom, degrees,
max(degreees) over (order by id rows between unbounded preceding and 1 preceding)
as max_degrees_before
from pitch_at_point
) data
where degrees < max_degrees_before;
这听起来好像可以用 window 函数解决。
这将为您提供一个 true/false 标志,用于记录先前的度数字段(按 ID 排序)大于当前行的度数:
case when degrees < max( degrees ) over(
order by id
rows between unbounded preceding and 1 preceding
)
then true
else false
end as higher_value_present
在此处查看 SQLfiddle:http://sqlfiddle.com/#!15/23196/1
根据你的问题,我不清楚是否有一组 id 用于你想要应用此逻辑的每个几何点?如果是这种情况,您可以按 geom:
对 window 函数进行分区
case when degrees < max( degrees ) over(
partition by geom
order by id
rows between unbounded preceding and 1 preceding
)
then true
else false
end as higher_value_present
我正在尝试使用 PostgreSQL 和 PostGIS 中的 SQL 解决视线 (LoS) 问题。为此,我有一个 table pitch_at_point
,其中包含一个 ID、一个点几何形状和一个间距。
pitch_at_point(id integer,geom geometry,degrees float)
id 列的最低值是视距的起点,最高值是最远的。对于这些点中的每一个,我想确定是否有任何点具有较低的 id,也具有较高的音高(度)。如果是这样的话,那点就看不出来了
我一直在寻找解决方案。我尝试使用递归查询,如下面的 SQL 所示:
WITH RECURSIVE
walk_points AS
(
SELECT ARRAY[id] AS idlist,geom,degrees,id
FROM pitch_at_point
WHERE degrees = (SELECT max(degrees) FROM pitch_at_point)
UNION ALL
SELECT array_append(w.idlist, n.id) AS idlist,n.geom,n.degrees,n.id
FROM pitch_at_point n, walk_points w
WHERE n.degrees < any(SELECT n.degrees FROM pitch_at_point WHERE NOT
w.idlist @> ARRAY[n.id])
)
SELECT * FROM walk_points
我希望得到一个 return 所有点之前有更高音高的点,但我只得到一个点的结果,即使我使用 WHERE n.degrees > any(
。
我很难弄清楚 PostgreSQL 递归 CTE,所以如果有人能帮助我,我将不胜感激。
我可能错了,但这不就是:
select
id, geom, degrees
from pitch_at_point
where exists
(
select *
from pitch_at_point before
where before.id < pitch_at_point.id
and before.degree > pitch_at_point.degree
);
这会获取 ID 较低的记录具有较高音高的所有点。
使用 MAX 的窗口版本可能会更快:
select id, geom, degrees
from
(
select
id, geom, degrees,
max(degreees) over (order by id rows between unbounded preceding and 1 preceding)
as max_degrees_before
from pitch_at_point
) data
where degrees < max_degrees_before;
这听起来好像可以用 window 函数解决。
这将为您提供一个 true/false 标志,用于记录先前的度数字段(按 ID 排序)大于当前行的度数:
case when degrees < max( degrees ) over(
order by id
rows between unbounded preceding and 1 preceding
)
then true
else false
end as higher_value_present
在此处查看 SQLfiddle:http://sqlfiddle.com/#!15/23196/1
根据你的问题,我不清楚是否有一组 id 用于你想要应用此逻辑的每个几何点?如果是这种情况,您可以按 geom:
对 window 函数进行分区 case when degrees < max( degrees ) over(
partition by geom
order by id
rows between unbounded preceding and 1 preceding
)
then true
else false
end as higher_value_present