我有以下表格(这些表格包含许多记录,但为了这个示例,我仅将内容缩减为我想要操作的记录)。
产品
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_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 完成的,但真正的问题需要用 ABAP 的 OpenSQL 来解决,所以我不能使用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
复合键中有一个...看起来我必须找到另一种方法或在链接表中寻找对我有帮助的其他字段。