Как сузить группу строк Postgres, по которым значения ближе всего к конкретным значениям? - PullRequest
0 голосов
/ 26 марта 2019

У меня есть некоторые данные, которые выглядят примерно так после запуска нескольких фильтров:

Business Type | Business City | Min Rating | Max Rating
--------------+---------------+------------+-----------
Restaurant    | Barcelona     |          2 |          8
Restaurant    | Barcelona     |          1 |         10
Restaurant    | Madrid        |          4 |          8
Diner         | Madrid        |          5 |          8
Diner         | Madrid        |          1 |          8
Diner         | Barcelona     |          3 |          8

Мне нужно вернуть только одну строку для каждого типа бизнеса и комбинации города.Строка, которую я возвращаю, должна быть той, где минимальные и максимальные оценки наиболее близки к определенным числам.Например, я хочу вернуть ближайший к минимальному рейтингу 3 и максимальному рейтингу 7. Это приведет к:

Business Type | Business City | Min Rating | Max Rating
--------------+---------------+------------+-----------
Restaurant    | Barcelona     |          2 |          8
Restaurant    | Madrid        |          4 |          8
Diner         | Madrid        |          5 |          8
Diner         | Barcelona     |          3 |          8

Это в приложении Rails 5, использующем ActiveRecord.Я открыт для использования Arel, ActiveRecord DSL или PostgreSQL.

1 Ответ

0 голосов
/ 26 марта 2019

Для этого вы можете определить собственную функцию агрегирования:

CREATE FUNCTION closer_to(integer, integer, integer) RETURNS integer
   LANGUAGE sql AS
'SELECT CASE WHEN abs($1 - $3) < abs($2 - $3) THEN $1 ELSE $2 END';

CREATE AGGREGATE closest_to(integer, integer) (
   STYPE = integer,
   SFUNC = closer_to
);

Тогда вы можете написать свой запрос как:

SELECT "Business Type", "Business City",
       closest_to("Min Rating", 3) AS "Min Rating",
       closest_to("Max Rating", 7) AS "Max Rating",
FROM mytable
GROUP BY "Business Type", "Business City";
...