字段定义表中的SQL内连接?

时间:2010-04-14 22:57:03

标签: sql

目前,我有一个共6个表,这是这个问题的一部分。主表tableA包含其他5个表中的所有条目共有的列。其他5个表中的列更详细地定义了表A中的条目。

例如:

TableA
ID|Name|Volume|Weight|Description
--+----+------+------+-----------
0 |T1  |0.4   |0.1   |Random text
1 |R1  |5.3   |25    |Random text

TableB
ID|Color|Shape
--+-----+------
0 |Blue |Sphere

TableC
ID|Direction|Velocity
--+---------+--------
1 |North    |3.4

(列名只是示例,不会因为它们的含义而将它们视为......)

表A中的ID字段对于所有其他表是唯一的(即TableB将具有0,但TableC将不会,也不会有任何其他表)。

我想做的是选择TableA中的所有字段和相应的(根据ID字段)详细信息表(表B-F)。

我目前所做的并且未经过测试的是向TableA添加了一个字段,所以它看起来像这样:

TableA
ID|Name|Volume|Weight|Description|Table
--+----+------+------+-----------+------
0 |T1  |0.4   |0.1   |Random text|TableB
1 |R1  |5.3   |25    |Random text|TableC

我对此有几个问题:

  1. 对TableA做这样的事情是否合适,因为外键在这种情况下不起作用,因为它们都需要链接到不同的表?

  2. 如果这是正确的,SQL查询是否会像这样(ID会由用户输入)?

    SELECT *
    FROM TableA AS a
    INNER JOIN a.Table AS t ON a.ID = ID;

  3. 有更好的方法吗?

  4. 感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

  1. 如果你说TableA是主表,那么所有细节表(TableB,TableC等)都应该在A上有FK,反之亦然。

  2. 要从TableA中选择记录,其他表中的所有详细信息都使用LEFT JOIN:

    SELECT A.*, B.color,B.shape, C.direction, C.velocity
    FROM TableA A
    LEFT JOIN TableB B ON (B.id = A.id)
    LEFT JOIN TableC B ON (C.id = A.id)

答案 1 :(得分:0)

这是处理超类型/子类型模型的常用方法。例如,Employee和Customer是Person的子类型......

PERSON

Id|PType|Name      
--+-----+----------
 1|EMP  |APC       
 2|CUS  |WOLF      
 3|CUS  |SUESS     

EMPLOYEE

Id|PType|Job      |Sal    |HireDate  |DeptNo      
--+-----+---------+-------+----------+------
 1|EMP  |PLUMBER  |   3500|20-MAY-09 |    50   

CUSTOMER

Id|PType|Ref      |CreditRating   
--+-----+---------+------------
 2|CUS  |W/10/2   |AAA    
 3|CUS  |S/10/3   |AA     

子类型表上的PType列的重复可能看起来有点奇怪。但它对于在子类型和超类型表之间强制执行强外键很有用。 PERSON表在(ID)上有一个主键,在(ID,PTYPE)上有一个唯一键。子类型在PTYPE上有一个CHECK约束;例如,在CUSTOMER上它会CHECK (ptype='CUS')。这意味着子类型可以在(ID,PTYPE)上具有外键,这确保CUSTOMER中的记录只能引用PTYPE为“CUS”的PERSON中的记录。

至于查询,你可能想做这样的事情来雇佣员工:

select p.*
       , e.job
       , e.sal
       , e.hiredate
       , e.deptno
from person p
     inner join employee e
     on ( p.id = e.id
          and p.ptype = e.ptype )
/

这是为了吸引顾客:

select p.*
       , c.ref
       , c.creditrating
from person p
     inner join customer c
     on ( p.id = c.id
          and p.ptype = c.ptype )
/

在连接条件中包含PTYPE是可选的,但它的存在可能有助于数据库优化器选择更好的执行路径。

可以使用外连接...

查询所有PERSON记录及其子类型列
select p.*
       , e.job
       , e.sal
       , e.hiredate
       , e.deptno
       , c.ref
       , c.creditrating
from person p
     left outer join employee e
     on ( p.id = e.id
          and p.ptype = e.ptype )
     left outer join customer c
     on ( p.id = c.id
          and p.ptype = c.ptype )
/

然而,这不是你应该轻易做的事情。有五个这样的表,外连接可能会产生非常差的访问路径。单独的查询可能比单个聚合查询执行得快得多。