查询返回超出我想要的子查询

时间:2015-01-29 12:51:05

标签: sql subquery inner-join in-subquery opensql

我有以下表格(这些表格包含许多记录但是为了这个例子我只将内容减少到我想要操作的记录)。

产品

 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_idstatusproduct_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 ...看起来我必须找到另一种方法或查找链接表中的其他字段那会对我有所帮助。

0 个答案:

没有答案