Как выбрать максимальное количество строк в неизвестный период.Postgres - PullRequest
0 голосов
/ 03 декабря 2018

У меня есть следующая таблица

create table order(
id serial PK,
status varchar(255),
finish_time date
)

Я хочу выбрать максимальное количество заказов со статусом = 'выполнено' в период между 3 днями

Например, скажем, яиметь такое содержание

select * from orders;

id | status | finish_time

1     'finish'  2018-09-10

1     'finish'  2018-09-11

1     'finish'  2018-09-12

1     'finish'  2018-09-12

от September 10 to 12 (3 дня) сумма будет 4.

от September 11 to 13 (3 дня) сумма будет 3

Такответ должен быть 4

Как мне написать такой запрос в Postgres?

Ответы [ 2 ]

0 голосов
/ 03 декабря 2018

В идеале вам нужны оконные функции, где range between работает с датами.Увы, Postgres (пока) не поддерживает это.

Вот другой подход:

select o.*, o2.cnt
from orders o cross join lateral
     (select count(*) as cnt
      from orders o2
      where o2.status = 'finish' and
            o2.finish_time >= o.finish_time - interval '3 day' and
            o2.finish_time <= o.finish_time
     ) o2
order by cnt desc
fetch first 1 row only;
0 голосов
/ 03 декабря 2018

Я бы использовал предложение where с датой больше, чем с подзапросом, чтобы получить максимальный день минус 3 дня (Запрос 1).

Или, если вы хотите конкретную дату с 3 предыдущими днями, предложение where с датой больше, чем для подзапроса с этой датой - 3 дня и меньше или равно этой дате (Проверьте запрос 2)

Например:

Схема(PostgreSQL v10.0)

CREATE TABLE orders (
  id INTEGER,
  status VARCHAR(8),
  finish_time DATE
);

INSERT INTO orders
  (id, status, finish_time)
VALUES
  ('1', 'finish', '2018-09-07'),
  ('2', 'finish', '2018-09-08'),
  ('3', 'finish', '2018-09-09'),
  ('4', 'finish', '2018-09-10'),
  ('5', 'pending', '2018-09-10'),
  ('6', 'finish', '2018-09-11'),
  ('7', 'finish', '2018-09-12'),
  ('8', 'finish', '2018-09-12'),
  ('9', 'pending', '2018-09-13');

Запрос № 1

SELECT * FROM orders o
WHERE o.status = 'finish'
AND o.finish_time > (SELECT MAX(ord.finish_time) - INTERVAL '3 DAY' FROM orders ord WHERE ord.status = 'finish');

Результат

| id  | status | finish_time              |
| --- | ------ | ------------------------ |
| 4   | finish | 2018-09-10T00:00:00.000Z |
| 6   | finish | 2018-09-11T00:00:00.000Z |
| 7   | finish | 2018-09-12T00:00:00.000Z |
| 8   | finish | 2018-09-12T00:00:00.000Z |

Запрос № 2

SELECT * FROM orders o
WHERE o.status = 'finish'
AND o.finish_time > (SELECT DATE('2018-09-11') - INTERVAL '3 DAY')
AND o.finish_time <= (SELECT DATE('2018-09-11'));

Результат

| id  | status | finish_time              |
| --- | ------ | ------------------------ |
| 3   | finish | 2018-09-09T00:00:00.000Z |
| 4   | finish | 2018-09-10T00:00:00.000Z |
| 6   | finish | 2018-09-11T00:00:00.000Z |

Показать наDB Fiddle

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