Повторное использование вычисляемых столбцов в том же запросе для других вычислений - PullRequest
0 голосов
/ 28 января 2020

Я должен использовать вычисляемые столбцы, чтобы вычислить значение другого столбца. Поскольку я работаю с очень большой таблицей, а также выполняю сложные вычисления для двух предыдущих столбцов, было бы нецелесообразно повторять те же функции для получения третьего столбца, поэтому ищу способ использовать подзапрос.

Моя таблица:

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

Я также добавил псевдоним в свой подзапрос, но это не сработало.

Я нашел этот ответ , который, кажется, работает для базы данных Oracle, но в моем случае это не работает (используется PostgreSQL). Я воспроизвожу минимальный рабочий пример в скрипке здесь , чтобы проиллюстрировать проблему.

Может кто-нибудь указать, что я здесь упустил или сделал не так?

1 Ответ

2 голосов
/ 28 января 2020

Подсказка подсказывает вам, что делать: присвойте подзапросу псевдоним:

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, если хотите получить среднее между двумя значениями.

Демо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...