Sql选择许多子表中的一个

时间:2015-12-31 19:34:01

标签: sql

我不是SQL的新手,但我不是贸易中的数据库管理员/设计师,因此遇到了一些难题。我有一个父表(父表有子表的共享属性)有8个孩子的东西。当我查询db时,我将需要来自父表的数据,并且一次只需要一个子节点,但是我无法确定如何通信从哪个子表中提取数据。父表和子表共享一个id。父表中的字段有可能成为要从中绘制子项的决策程序。例如:

parent id machine 1 N1 2 S8 3 P6

仅包含与具有“N”型机器(N1,N2,N3,...)的父记录关联的记录。 child1 id ...some other columns 1

仅包含与具有“S”型机器(S1,S2,S3,...)的父记录关联的记录。 child2 id ...some other columns 2

仅包含与具有“P”型机器(P1,P2,P3,...)的父记录关联的记录。 child3 id ...some other columns 3

我认为这里的几个逻辑可能性看起来效率不高:
1)依次搜索每个子表以获取父项记录的id。

2)使用join语句创建一个视图,该语句包含附加到关联父记录的所有子表记录。难道这不会变成一个巨大的零值格仔甜头吗? sql fiddle

3)为每个子表创建一个视图,将父记录和子记录连接成一个。使用另一种语言创建一种机制,将机器转换为其类型(例如:如果我想要N1的记录,则代码将为包含child1的视图设置查询'table'(N类型机器表)。(也许是三个最好的选项???)sql fiddle

我情不自禁地觉得我在这里遗漏了一些东西,一些SQL魔法会让这个问题看起来微不足道,但是网络间的分析却没有产生任何结果。你能给我的任何东西都将不胜感激。谢谢你。

2 个答案:

答案 0 :(得分:0)

您可以采用JOIN方式对所有表格LEFT JOIN进行生成,然后使用COALESCE表示所有这些表格SELECTSELECT p.id, P.machine, P.someField, COALESCE(C1.field, C2.field, C3.field) field FROM parent P LEFT JOIN child1 C1 ON C1.id = P.id AND LEFT(P.machine, 1) = 'N' LEFT JOIN child2 C2 ON C2.id = P.id AND LEFT(P.machine, 1) = 'S' LEFT JOIN child3 C3 ON C3.id = P.id AND LEFT(P.machine, 1) = 'P';

Child

然而,这样做非常昂贵。

更好的方法是让一个MachineType Char(1)表具有它所在的机器类型(例如:N列只有SPUNION ALL等,而不是使用8个不同的表格。

另一种选择是使用SELECT p.id, P.machine, P.someField, C1.field field FROM parent P JOIN child1 C1 ON C1.id = P.id WHERE LEFT(P.machine, 1) = 'N' UNION ALL SELECT p.id, P.machine, P.someField, C2.field field FROM parent P JOIN child2 C2 ON C2.id = P.id WHERE LEFT(P.machine, 1) = 'S' UNION ALL SELECT p.id, P.machine, P.someField, C3.field field FROM parent P JOIN child3 C3 ON C3.id = P.id WHERE LEFT(P.machine, 1) = 'P' 分别引入项目:

supervisord.conf

答案 1 :(得分:0)

如果这是一个更有利的输出,您可以将每个子表格展开成列名称/值并在视图中将它们合并在一起。基于你的SQL小提琴:

--Unpivoted Children 
CREATE VIEW unpvt_child AS
--N Machine Children
SELECT 
  unpvt.id,
  unpvt.col_name,
  unpvt.col_value
FROM
  (SELECT id, c1_field1
   FROM child1) p
UNPIVOT
  (col_value FOR col_name IN
     (c1_field1)
)AS unpvt
UNION ALL

--S Machine Children
SELECT 
  unpvt.id,
  unpvt.col_name,
  unpvt.col_value
FROM
  (SELECT id, c2_field1
   FROM child2) p
UNPIVOT
  (col_value FOR col_name IN
     (c2_field1)
)AS unpvt;

这会给你一个这样的输出:

id, col_name, col_value
1, c1_field1, N machine stuff
2, c2_field1, S machine stuff

如果我理解了模式,那么主键是id与子表一对一的id,所以新的连接很简单:

SELECT 
  * 
FROM
  parent p
LEFT JOIN
  unpvt_child c ON c.id = p.id;

SQL小提琴:http://sqlfiddle.com/#!6/aa5f33/1

您的最终输出可能如下所示:

id, machine, someField, child_attribute, child_value
1, N1, blah, c1_field1, N machine stuff
2, S8, moreblah, c2_field1, S machine stuff