目前,我有一个共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
我对此有几个问题:
对TableA做这样的事情是否合适,因为外键在这种情况下不起作用,因为它们都需要链接到不同的表?
如果这是正确的,SQL查询是否会像这样(ID会由用户输入)?
SELECT *
FROM TableA AS a
INNER JOIN a.Table AS t ON a.ID = ID;
有更好的方法吗?
感谢您的帮助。
答案 0 :(得分:1)
如果你说TableA是主表,那么所有细节表(TableB,TableC等)都应该在A上有FK,反之亦然。
要从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 )
/
然而,这不是你应该轻易做的事情。有五个这样的表,外连接可能会产生非常差的访问路径。单独的查询可能比单个聚合查询执行得快得多。