PostgreSQL - запрос второй таблицы с несколькими результатами - PullRequest
0 голосов
/ 29 августа 2018

Я работаю в PostgreSQL 9.6.6 над запросом, который предполагает использование второй таблицы для возврата дополнительных точек данных. Таблица - «события» - связана со многими записями из второго - «действия» - через внешний ключ.

События

| id | name   |
|----|--------|
| 1  | event1 |
| 2  | event2 |
| 3  | event3 |

Мероприятия

| id | name      | startDate              | endDate                | status    | eventId |
|----|-----------|------------------------|------------------------|-----------|---------|
| 1  | activity1 | 2018-08-27 05:00:00+00 | 2018-08-28 05:00:00+00 | Draft     | 1       |
| 2  | activity2 | 2018-09-27 05:00:00+00 | 2018-09-27 10:00:00+00 | Submitted | 1       |
| 3  | activity3 | 2018-08-25 05:00:00+00 | 2018-08-27 10:00:00+00 | Draft     | 1       |
| 4  | activity4 | 2018-08-21 05:00:00+00 | 2018-08-24 05:00:00+00 | Approved  | 2       |
| 5  | activity5 | 2018-09-27 05:00:00+00 | 2018-09-29 05:00:00+00 | Draft     | 2       |
| 6  | activity6 | 2018-10-27 05:00:00+00 | 2018-10-28 05:00:00+00 | Approved  | 3       |
| 7  | activity7 | 2018-08-27 05:00:00+00 | 2018-08-27 10:00:00+00 | Approved  | 3       |

Точками данных, собираемыми с помощью события, являются startDate, endDate & status на основе связанных действий.

  • startDate => Наименьшая начальная дата всех связанных действий.
  • endDate => Величайшая конечная дата всех связанных действий.
  • status => Статус равен «Ожидание», если не все связанные действия имеют статус «Одобрено» (тогда статус равен «Завершено»).

Пример возвращаемого запроса будет выглядеть так:

| id | name   | startDate              | endDate                | status    |
|----|--------|------------------------|------------------------|-----------|
| 1  | event1 | 2018-08-25 05:00:00+00 | 2018-09-27 10:00:00+00 | Pending   |
| 2  | event2 | 2018-08-21 05:00:00+00 | 2018-09-29 05:00:00+00 | Pending   |
| 3  | event3 | 2018-08-27 05:00:00+00 | 2018-10-28 05:00:00+00 | Completed |

Я сформулировал следующее с несколькими подзапросами, но производительность ужасна.

Как я могу улучшить это, чтобы ограничить (или даже удалить) использование подзапросов?

SELECT DISTINCT ON("startDate", "event"."name") 1, "event"."id", "event"."name", (
  SELECT "activities"."startDate"
  FROM "events"
  INNER JOIN "activities" AS "activities" ON "event"."id" = "activities"."eventId"
  WHERE "event"."id" = "activities"."eventId"
  ORDER BY "event"."id" ASC, "activities"."startDate" ASC
  LIMIT 1
) AS "startDate", (
  SELECT "activities"."endDate"
  FROM "events"
  INNER JOIN "activities" AS "activities" ON "event"."id" = "activities"."eventId"
  WHERE "event"."id" = "activities"."eventId"
  ORDER BY "event"."id" ASC, "activities"."endDate" DESC
  LIMIT 1
) AS "endDate", (
  SELECT DISTINCT ON("event"."id")
    CASE "activities"."status"
    WHEN 'Draft' THEN 'Pending'
    WHEN 'Submitted' THEN 'Pending'
    ELSE 'Complete'
    END
  FROM "events"
  INNER JOIN "activities" AS "activities" ON "event"."id" = "activities"."eventId"
  WHERE "event"."id" = "activities"."eventId"
  ORDER BY "event"."id" ASC, "activities"."status" DESC
) AS "status"
FROM "events" AS "event"
ORDER BY "startDate" DESC, "event"."name" ASC
LIMIT 20
OFFSET 0;

1 Ответ

0 голосов
/ 29 августа 2018

Я думаю, вы хотите агрегации. Ваша логика и результаты подсказывают:

select eventid, min(startDate), max(endDate),
       (case when min(status) = max(status) and min(status) = 'Approved'
             then 'Approved'
             else 'Pending'
        end) as status
from activities a
group by eventid;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...