PostgreSQL Функция MIN и MAX не возвращает один результат - PullRequest
0 голосов
/ 01 мая 2020

В PostgreSql DB у меня есть таблица с именем Trip.

В таблице есть столбец с именем id и столбец с именем meta.

Пример id в одной строке выглядит следующим образом:

id = 123456

Пример meta в одной строке выглядит следующим образом:

meta = {"runTime": 3922000, "distance": 85132, "duration": 4049000, "fuelUsed": 19.595927498516176}

Я хочу выбрать поездку с минимальным kph из таблицы Trip и показать идентификатор поездки и минимальное kph. Это мой запрос:

select tp."id" tripid, MIN((3600 * (tp."meta"->>'distance')::numeric)
   / ((tp."meta"->>'runTime')::NUMERIC)) minkph FROM "Trip" tp 
WHERE tp."createdAt" BETWEEN '2020-04-01 00:00:00+00'
                      and '2020-04-30 00:00:00+00'
GROUP BY tp."id"

Однако этот запрос возвращает результаты всех идентификаторов командировок и расчетов, а не только одну строку.

Не могли бы вы помочь?

Ответы [ 2 ]

1 голос
/ 01 мая 2020

Вы можете order by вычисленное kph поле и вернуть только первое:

select tp."id" tripid, MIN((3600 * (tp."meta"->>'distance')::numeric)
   / ((tp."meta"->>'runTime')::NUMERIC)) minkph FROM "Trip" tp 
WHERE tp."createdAt" BETWEEN '2020-04-01 00:00:00+00'
                      and '2020-04-30 00:00:00+00'
GROUP BY tp."id"
order by 2
limit 1
1 голос
/ 01 мая 2020

Подход 1 - Общие мин. По идентификатору:

Вы выражаете столбец tp.id в своем запросе, поэтому ваш выбор будет запускать MIN() для каждой группы id. Если вам нужен глобальный MIN() для вашего запроса, просто сделайте так:

SELECT MIN((3600 * (tp."meta"->>'distance')::numeric) / ((tp."meta"->>'runTime')::NUMERIC)) minkph 
  FROM "Trip" tp 
 WHERE tp."createdAt" BETWEEN '2020-04-01 00:00:00+00' 
   AND '2020-04-30 00:00:00+00'

Каждая групповая функция группирует набор различных данных, если вы не передаете ни одного столбца, кроме MIN(), запрос приведет глобальный результат в одну строку для всех строк.

Подход 2 - Общий мин.:

Если вы хотите получить MIN() и соответственно id, вы можете сделать следующее и сделать LIMIT 1. как есть:

    SELECT tp."id" AS tripid, ((3600 * (tp."meta"->>'distance')::numeric) / ((tp."meta"->>'runTime')::NUMERIC)) minkph 
      FROM "Trip" tp 
     WHERE tp."createdAt" BETWEEN '2020-04-01 00:00:00+00' 
       AND '2020-04-30 00:00:00+00'
     ORDER BY 2
     LIMIT 1

во времени. Вы можете использовать оконные функции, но это немного сложно сделать.

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