我必须使用计算列来计算另一列的值。因为我使用的是非常大的表,并且还对前两列进行了复杂的计算,所以重复相同的函数来派生第三列并不是一个好主意,因此寻找一种使用子查询的方法。 / p>
我的桌子:
SELECT * FROM my_table LIMIT 5;
session_id | seconds | millis | gpstime | gpsmillis | nsats | lat | lon | alt | track | speed | acc
------------+------------+--------+------------+-----------+-------+------------+------------+-----+-------+---------+-----
14026 | 1460464791 | 264 | 1460464791 | 264 | -1 | 41.178237 | -8.5947137 | 0 | 0 | 0 | 20
14026 | 1460464983 | 970 | 1460464983 | 970 | -1 | 41.177956 | -8.5953581 | 234 | 67 | 10.2583 | 25
14026 | 1460464984 | 712 | 1460464984 | 712 | -1 | 41.1780008 | -8.5952012 | 182 | 58 | 9.19696 | 31
14026 | 1460464985 | 700 | 1460464985 | 700 | -1 | 41.1779522 | -8.595209 | 196 | 74 | 7.63053 | 19
14026 | 1460464986 | 714 | 1460464986 | 714 | -1 | 41.177981 | -8.5951491 | 196 | 74 | 5.51359 | 22
(5 rows)
然后,我运行下面的查询,以在子查询中计算a1
和a2
,并在主查询中将它们平均为acceleration
。
SELECT session_id
, gpstime
, lat
, lon
, track AS heading
, speed
, AVG(a1, a2) AS acceleration
FROM (
SELECT *
,((LEAD(speed) OVER (ORDER BY gpstime)) - speed) /
(((LEAD(gpstime) OVER (ORDER BY gpstime)) - gpstime) +0.001) AS a2
, (speed - (LAG(speed) OVER (ORDER BY gpstime))) /
(gpstime - (LAG(gpstime) OVER (ORDER BY gpstime)) + 0.001) AS a1
FROM my_table
);
错误:
ERROR: subquery in FROM must have an alias
LINE 9: (
^
HINT: For example, FROM (SELECT ...) [AS] foo.
SQL state: 42601
Character: 111
我还向子查询添加了别名,但是没有用。
我发现了这个answer,它似乎适用于Oracle数据库,但是在我的情况下(使用PostgreSQL)却不起作用。我在小提琴here中重现了一个最小的工作示例,以说明问题。
有人可以指出我在这里错过或做错了什么吗?
答案 0 :(得分:2)
提示告诉您该怎么做:给子查询一个别名:
SELECT session_id
, gpstime
, lat
, lon
, track AS heading
, speed
, AVG(a1) AS acceleration
FROM (
SELECT *
,((LEAD(speed) OVER (ORDER BY gpstime)) - speed) /
(((LEAD(gpstime) OVER (ORDER BY gpstime)) - gpstime) +0.001) AS a2
, (speed - (LAG(speed) OVER (ORDER BY gpstime))) /
(gpstime - (LAG(gpstime) OVER (ORDER BY gpstime)) + 0.001) AS a1
FROM my_table
) as sub; --<< HERE
但是AVG(a1, a2)
也是错误的。
avg()
是一个聚合函数,适用于单列和独立行。因此,您需要使用avg(a1)
或avg(a2)
,或者如果想要两个值之间的平均值,则可能需要(a1 + a2) / 2
。