Запрос с подзапросами возвращает больше, чем я хочу

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

Товары

 product_id | product_name 
------------+--------------
          1 | PRODUCT

контракты

 contract_id | version | status | product_id 
-------------+---------+--------+------------
           2 |       1 | 30     |          1
           2 |       2 | 30     |          1
           2 |       3 | 30     |          1
           2 |       4 | 30     |          1
           2 |       5 | 30     |          1
           2 |       6 | 30     |          1

люди

 id | guid 
----+------
  3 |  123
  9 |  456

рамки

 id | type 
----+------
  4 | 12
  5 | 14

Link_table

 link_id | version | contract_id | object_type | function | obj_id 
---------+---------+-------------+-------------+----------+--------
       6 |       1 |           2 | XADL        | ADLTYP   |      4
       7 |       2 |           2 | XADL        | ADLTYP   |      5
       8 |       2 |           2 | BCBP        | BCA010   |    123
      10 |       3 |           2 | BCBP        | BCA010   |    456

Вот DDL для вышеупомянутых таблиц...

CREATE TABLE products (
  product_id    integer PRIMARY KEY,
  product_name  varchar(10) NOT NULL
);

CREATE TABLE contracts (
  contract_id   integer,
  version   integer,
  status    varchar(2) NOT NULL,
  product_id    integer NOT NULL REFERENCES products(product_id),
  PRIMARY KEY (contract_id, version)
);

CREATE TABLE link_table (
  link_id   integer,
  version   integer,
  contract_id   integer NOT NULL,
  object_type   varchar(4) NOT NULL,
  function  varchar(6) NOT NULL,
  obj_id    integer NOT NULL,
  PRIMARY KEY(link_id, version)
);

CREATE TABLE people (
  id    integer PRIMARY KEY,
  guid  integer,
  CONSTRAINT person_guid UNIQUE(guid)
);

CREATE TABLE limits (
  id    integer PRIMARY KEY,
  type  varchar(2) NOT NULL
);

Сейчас... Моя задача - выбрать последнюю версию значения для поля type в limits таблица для последней версии значения id в people Таблица. Стол link_table решает, какая последняя версия. Эти данные должны быть предоставлены с полями contract_id, status, product_name,

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

SELECT c.contract_id, status, product_name, type
  FROM
    contracts AS c
  INNER JOIN
    products AS p
  ON c.product_id = p.product_id
  INNER JOIN
    link_table AS per
  ON c.contract_id = per.contract_id
  INNER JOIN
    link_table AS ll
  ON per.contract_id = ll.contract_id
  INNER JOIN
    people AS peop
  ON per.obj_id = peop.guid
  INNER JOIN
    limits AS lim
  ON ll.obj_id = lim.id
  WHERE 
    peop.id = 3
    AND per.object_type = 'BCBP'
    AND per.function = 'BCA010'
    AND ll.object_type = 'XADL'
    AND ll.function = 'ADLTYP'
    AND ll.version IN ( SELECT max(version) FROM link_table WHERE link_id = ll.link_id)
    AND per.version IN ( SELECT max(version) FROM link_table WHERE link_id = per.link_id)
    AND c.version IN ( SELECT max(version) FROM contracts WHERE contract_id = c.contract_id );

Результат, который я ожидаю

 contract_id | status | product_name | type 
-------------+--------+--------------+------
           2 | 30     | PRODUCT      | 12

Однако фактический результат

 contract_id | status | product_name | type 
-------------+--------+--------------+------
           2 | 30     | PRODUCT      | 12
           2 | 30     | PRODUCT      | 14

Я боролся с этим уже больше суток. Может кто-нибудь сказать мне, что я делаю не так? Этот пример сделан с PostgreSQL, но реальная проблема должна быть решена с OpenAP ABAP, поэтому я не могу использовать UNION,

Вот немного SQL для заполнения таблиц.

INSERT INTO products VALUES (1, 'PRODUCT');
INSERT INTO contracts VALUES (2, 1, '30', 1);
INSERT INTO contracts VALUES (2, 2, '30', 1);
INSERT INTO contracts VALUES (2, 3, '30', 1);
INSERT INTO contracts VALUES (2, 4, '30', 1);
INSERT INTO contracts VALUES (2, 5, '30', 1);
INSERT INTO contracts VALUES (2, 6, '30', 1);
INSERT INTO people VALUES (3, 123);
INSERT INTO people VALUES (9, 456);
INSERT INTO limits VALUES (4, '12');
INSERT INTO limits VALUES (5, '14');
INSERT INTO link_table VALUES (6, 1, 2, 'XADL', 'ADLTYP', 4);
INSERT INTO link_table VALUES (7, 2, 2, 'XADL', 'ADLTYP', 5);
INSERT INTO link_table VALUES (8, 2, 2, 'BCBP', 'BCA010', 123);
INSERT INTO link_table VALUES (10, 3, 2, 'BCBP', 'BCA010', 456);

РЕДАКТИРОВАТЬ

Похоже, если следующие записи в table_link

 link_id | version | contract_id | object_type | function | obj_id 
---------+---------+-------------+-------------+----------+--------
       6 |       1 |           2 | XADL        | ADLTYP   |      4
       7 |       2 |           2 | XADL        | ADLTYP   |      5

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

 link_id | version | contract_id | object_type | function | obj_id 
---------+---------+-------------+-------------+----------+--------
       7 |       1 |           2 | XADL        | ADLTYP   |      4
       7 |       2 |           2 | XADL        | ADLTYP   |      5

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

0 ответов

Другие вопросы по тегам