2010-04-14 38 views
1

我有一个,目前,共有6个表是这个问题的一部分。主表tableA包含其他5个表中所有条目具有共同性的列。其他5个表格有更详细地定义表格A中的条目的列。来自字段定义表的SQL内部联接?

例如:

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字段)细节表(TableB-F)中选择所有字段。

我所目前做,没有测试添加一个字段,表A,所以它看起来是这样的:

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. 有没有更好的方式来做到这一点?

感谢您的帮助。

回答

1
  1. 如果说表A是主表,那么所有详细信息表(表B,表C等)应具有上的一个FK,而不是相反。

  2. 要选择从表A的记录,并从其他表中的所有细节使用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)

+0

如果总是填充列,那么内部连接就可以了 – 2010-04-15 02:01:02

0

这是处理超类型/子类型的模型的常用方法。例如,员工和客户是子类型的人......

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  

上的分型表p型列的复制可能看起来有点怪。但是在子类型和超类型表之间执行强大的外键是很有用的。 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是可选但它的存在可能有助于数据库优化器选择更好的执行路径。

有可能通过使用外连接的查询所有与他们的分型列的个人记录...

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) 
/

然而,这是不是你应该做掉以轻心。有五个这样的表,外连接可能会产生很差的访问路径。单独的查询可能比单个聚集查询的执行速度快得多。