0

我有一个规范化的数据库,其中包含 3 个表,其 DDL 是:

CREATE CACHED TABLE Clients ( 
    cli_id       INTEGER       GENERATED ALWAYS AS IDENTITY (START WITH 100) PRIMARY KEY,
    defmrn_id    BIGINT,
    lastName     VARCHAR(48)   DEFAULT '' NOT NULL,
    midName      VARCHAR(24)   DEFAULT '' NOT NULL,
    firstName    VARCHAR(24)   DEFAULT '' NOT NULL,
    doB          INTEGER       DEFAULT 0 NOT NULL,
    gender       VARCHAR(1)    NOT NULL);

CREATE TABLE Client_MRNs (
    mrn_id       BIGINT        GENERATED ALWAYS AS IDENTITY (START WITH 100) PRIMARY KEY,
    cli_id       INTEGER       REFERENCES Clients ( cli_id ),
    inst_id      INTEGER       REFERENCES Institutions ( inst_id ),
    mrn          VARCHAR(32)   DEFAULT '' NOT NULL,

    CONSTRAINT climrn01 UNIQUE (mrn, inst_id));

CREATE TABLE Institutions ( 
    inst_id      INTEGER       GENERATED ALWAYS AS IDENTITY (START WITH 100) PRIMARY KEY,
    loc_id       INTEGER       REFERENCES Locales (loc_id ),
    itag         VARCHAR(6)    UNIQUE NOT NULL,
    iname        VARCHAR(80)   DEFAULT '' NOT NULL);

第一个表包含一个外键列 defmrn_id,它是对存储在第二个表中的“默认标识符代码”的引用(它是所有标识符代码的列表)。第一个表中的一条记录可能有很多标识符,但只有一个默认标识符。所以是的,我创建了一个循环引用。

第三个表只是来自第二个表的标准化数据。

我想要一个查询,该查询将基于将提供的标识符代码与可能属于该 CLIENT 记录的 CLIENT_MRN 中的任何标识符代码匹配来查找 CLIENT 记录。

我的策略是首先识别在第二个表 (CLIENT_MRN) 中匹配的那些记录,然后使用该中间结果连接到 CLIENT 表中与其他用户提供的搜索条件匹配的记录。我还需要对第一个表中的标识符引用 defmrn_id 进行非规范化。这是我想出的...

SQL = SELECT c.*, r.mrn, i.inst_id, i.itag, i.iname 
FROM Clients AS c 
INNER JOIN 
  (   
      SELECT m.cli_id   
      FROM Client_MRNs AS m   
      WHERE m.mrn = ? 
  ) AS m2 ON m2.cli_id = c.cli_id 
INNER JOIN Client_MRNs AS r ON c.defmrn_id = r.mrn_id 
INNER JOIN Institutions AS i USING ( inst_id )  
WHERE (<other user supplied search criteria...>);

以上工作,但我花了一些时间试图理解为什么以下不工作......

SQL = SELECT c.*, r.mrn, i.inst_id, i.itag, i.iname 
FROM Clients AS c 
INNER JOIN 
  (   
      SELECT m.cli_id   
      FROM Client_MRNs AS m   
      WHERE m.mrn = ? 
  ) AS m2  USING ( cli_id ) 
INNER JOIN Client_MRNs AS r ON c.defmrn_id = r.mrn_id 
INNER JOIN Institutions AS i USING ( inst_id )  
WHERE (<other user supplied search criteria...>);

在我看来,第二个 SQL 应该可以工作,但每次都在 USING 子句上失败。我正在对由 HSQLDB 2.2.9 作为 RDBMS 管理的数据库执行这些查询。这是 HSQLDB 中的解析问题还是嵌套查询的 USING 子句的已知限制?

4

1 回答 1

1

您始终可以尝试使用 HSQLDB 2.3.0(一个候选版本)。

您报告不完整 SQL 的方式不允许正确检查。但是查询中有一个明显的错误。如果你有:

SELECT INST_ID FROM CLIENTS_MRS AS R INNER JOIN INSTITUTIONS AS I USING (INST_ID)

INST_ID 只能在没有表限定符的情况下用于 SELECT 列列表。原因是它不再被视为任一表的列。如果使用 NATURAL JOIN,公共列也是如此。

此查询已被 2.3.0 版接受

SELECT c.*, r.mrn, inst_id, i.itag, i.iname 
FROM Clients AS c 
INNER JOIN 
  (   
      SELECT m.cli_id   
      FROM Client_MRNs AS m   
      WHERE m.mrn = 2 
  ) AS m2  USING ( cli_id ) 
INNER JOIN Client_MRNs AS r ON c.defmrn_id = r.mrn_id 
INNER JOIN Institutions AS i USING ( inst_id )  
于 2013-04-17T01:17:07.463 回答