Как выбрать из нескольких таблиц в группе по запросу? - PullRequest
0 голосов
/ 23 мая 2018

У меня есть несколько таблиц базы данных, содержащих некоторые документы, которые люди должны подписать.Таблицы определены (несколько упрощенно) следующим образом.

create table agreement (
    id integer NOT NULL,
    name character varying(50) NOT NULL,
    org_id integer NOT NULL,
    CONSTRAINT agreement_pkey PRIMARY KEY (id)
    CONSTRAINT org FOREIGN KEY (org_id) REFERENCES org (id) MATCH SIMPLE
)

create table version (
    id integer NOT NULL,
    content text NOT NULL,
    publish_date timestamp NOT NULL,
    agreement_id integer NOT NULL,
    CONSTRAINT version_pkey PRIMARY KEY (id)
    CONSTRAINT agr FOREIGN KEY (agreement_id) REFERENCES agreement (id) MATCH SIMPLE
)

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

SELECT a.id, a.name FROM agreement AS a
JOIN version as v ON (a.id = v.agreement_id)
JOIN org as o ON (o.id = a.org_id)
WHERE o.name = $1
GROUP BY a.id

Это, кажется, дает мне одну запись для каждого соглашения, которое принадлежит организации, которую я хочу, и имеет по крайней мере одну версию.Но мне нужно также указать содержание и дату публикации последней доступной версии.Как мне это сделать?

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

Редактировать: отразил необходимость в присоединении к org, поскольку я скорее выбираю orgs по именичем по id

Ответы [ 3 ]

0 голосов
/ 23 мая 2018

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

SELECT a.id, a.name, v.*
FROM agreement a JOIN
     version v
     ON a.id = v.agreement_id
WHERE a.org_id = $1 AND
      v.publish_date = (SELECT MAX(v2.publish_date) FROM version v2 WHERE v2.agreement_id = v.agreement_id);

Примечания:

  • Таблица org не нужна, поскольку agreement имеет org_id.
  • Агрегация не требуется для этого запроса.Вы фильтруете самую последнюю запись.
  • Коррелированный подзапрос - это один из методов, который извлекает самую последнюю версию.
0 голосов
/ 23 мая 2018

Postgresql имеет Функции окна .Оконные функции позволяют вам выполнять сортировку определенного столбца или набора столбцов.функция ранга возвращает место строки в результатах сортировки.Если вы отфильтруете только до ранга, равного 1, вы всегда получите только одну строку, и она будет отсортирована по наибольшему количеству для раздела.

select u.id, u.name, u.content, u.publish_date from (
SELECT a.id, a.name, v.content, v.publish_date, rank() over (partition by a.id order by v.id desc) as pos
FROM agreement AS a
JOIN version as v ON (a.id = v.agreement_id)
JOIN org as o ON (o.id = a.org_id)
WHERE o.id = $1
) as u
where pos = 1
0 голосов
/ 23 мая 2018
SELECT a.id, a.name, max(v.publish_date) publish_date FROM agreement AS a
JOIN version as v ON (a.id = v.agreement_id)
JOIN org as o ON (o.id = a.org_id)
WHERE o.id = $1
GROUP BY a.id, a.name
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...