我正在使用智能手机从加速计收集数据,然后将其保存在服务器的postgresql数据库中。基本上,每次我读取加速度计时,我都会保存智能手机当前的纬度/经度,以及它发生的时间戳。
现在,我想从数据库中读取每个不同位置(纬度/经度)的顺序与保存顺序(按时间戳排序)。而且我想知道每个位置有多少读数重复。
让我举个例子来解释一下。考虑我的数据库中有以下表格:
+------------+------------+-----------+
| latitude | longitude | timestamp |
+------------+------------+-----------+
| 43.1784771 | -8.5956853 | 930560045 |
| 43.1784771 | -8.5956853 | 930560054 |
| 41.2784813 | -7.5956853 | 930560063 |
| 42.1786173 | -8.5951757 | 930560072 |
| 42.1786173 | -8.5951757 | 930560082 |
+------------+------------+-----------|
请注意,我有按时间戳排序的元素,并且我有2个重复的位置。所以,我想查询数据库以查看重复的位置并得到以下结果:
+------------+------------+-------+
| latitude | longitude | count |
+------------+------------+-------+
| 43.1784771 | -8.5956853 | 2 |
| 41.2784813 | -7.5956853 | 1 |
| 42.1786173 | -8.5951757 | 2 |
+------------+------------+-------|
问题在于我希望将元素排序为原始表(按时间戳排序)。 我正在尝试以下查询,但它不起作用,因为子查询中的顺序并不重要:
SELECT latitude, longitude, count(*)
FROM
(SELECT latitude, longitude, timestamp FROM table ORDER BY timestamp asc) subquery1
GROUP BY latitude, longitude
我一直在寻找StackOverflow的答案,最接近的是这个:Is order in a subquery guaranteed to be preserved? 但是,它不适用于我的情况,因为我需要" group by"条款。有人可以帮帮我吗?
答案 0 :(得分:3)
SELECT
latitude,
longitude,
count(1) as "Count",
min(timestamp) as "Start",
max(timestamp) as "End"
FROM table
GROUP BY latitude, longitude
ORDER BY min(timestamp) asc
答案 1 :(得分:1)
create or replace function foo(
out latitude numeric,
out longitude numeric,
out cnt int,
out start_time numeric,
out end_time numeric
) returns setof record as $$
declare
c record;
p record;
i int := 1;
begin
select null into p;
for c in (select * from table order by timestamp)
loop
if p is null then
start_time := c.timestamp;
elsif p.latitude <> c.latitude and p.longitude <> c.longitude then
latitude := p.latitude;
longitude := p.longitude;
cnt := i;
end_time := p.timestamp;
return next;
i := 1;
start_time := p.timestamp;
else
i := i + 1;
end if;
p := c;
end loop;
if p.latitude = c.latitude and p.longitude = c.longitude then
latitude := p.latitude;
longitude := p.longitude;
cnt := i;
end_time := p.timestamp;
return next;
end if;
return;
end; $$ immutable language plpgsql;
用法:
select * from foo();
作为一点奖励,它还为每个系列提供开始/结束时间戳。
答案 2 :(得分:0)
子查询不会保留排序,但可以为array_agg操作定义它,我们可以使用它来确定更广泛的排序。尝试以下示例:
SELECT latitude, longitude, count(*), (array_agg(timestamp order by timestamp))[1] as first_time
FROM table GROUP BY latitude, longitude;
在OP的情况下,min(timestamp)可能更简单,但是如果排序更复杂,这可能是一个更整洁的选择。