Sql选择多个子表之一

Sql选择多个子表之一,sql,Sql,我对SQL并不陌生,但我不是一名db经理/设计师,因此遇到了一些难题。我有一个父表(父表有子表的共享属性),它有8个子表。当我查询数据库时,我需要来自父表的数据,一次只需要一个子表,但是我很难确定如何与哪个子表通信。父表和子表共享一个id。父表中的字段有可能成为从中提取子表的决策者。例如: parent id机 1 N1 2 S8 3 P6 仅包含与具有“N”类型计算机(N1、N2、N3,…)的父记录关联的记录。 child1 id…其他一些列 1 仅包含与具有“S”类型计算机(S1、S2、S3

我对SQL并不陌生,但我不是一名db经理/设计师,因此遇到了一些难题。我有一个父表(父表有子表的共享属性),它有8个子表。当我查询数据库时,我需要来自父表的数据,一次只需要一个子表,但是我很难确定如何与哪个子表通信。父表和子表共享一个id。父表中的字段有可能成为从中提取子表的决策者。例如:

parent
id机
1 N1
2 S8
3 P6

仅包含与具有“N”类型计算机(N1、N2、N3,…)的父记录关联的记录。
child1
id…其他一些列
1

仅包含与具有“S”类型计算机(S1、S2、S3,…)的父记录关联的记录。
child2
id…其他一些列
2

仅包含与具有“p”类型计算机(P1、P2、P3,…)的父记录关联的记录。
child3
id…其他一些列
3

我在这里看到了几个似乎效率不高的逻辑可能性:
1) 依次在每个子表中搜索父表中记录的id

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

3) 为每个子表创建一个视图,将父记录和子记录连接到一个表中。用另一种语言创建某种机制,将机器翻译成它的类型(例如:如果我想要
N1
的记录,所述代码将为包含child1的视图(
N
type机器表)设置查询“表”。(可能是三种机器表中最好的选择?)


我忍不住觉得我在这里遗漏了一些东西,一些SQL魔法会让这个问题看起来很简单,但是对inter-webs的搜索没有产生任何结果。您能给我的任何东西都将不胜感激。非常感谢。

您可以做这些
连接的方法是对所有表进行
左连接选择产品类型,然后在
选择中对所有产品使用
合并

SELECT      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';
然而,这样做是非常昂贵的

一种更好的方法是使用一个具有其所在机器类型的
子表(例如,
MachineType Char(1)
列,该列中只有
N
S
p
等),而不是使用8个不同的表

另一种选择是使用
UNION ALL
单独引入项目:

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'

您可以将每个子表解压为列名/值,并将它们合并到一个视图中(如果这是一个更有利的输出)。根据您的SQL FIDLE:

--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, machine, someField, child_attribute, child_value
1, N1, blah, c1_field1, N machine stuff
2, S8, moreblah, c2_field1, S machine stuff
如果我理解模式,主键是id,它与子表是一对一的,因此新的连接很简单:

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

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

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

在这里,我假设所有
CHILD
表都包含相同类型的列。您是否可以在一个新表中插入所有
CHILD
表数据,并添加一个额外的
MACHINE\u TYPE
指示符列,如P6、S8。
MACHINE\u TYPE
也将帮助您
PARENT
表连接。不幸的是,没有ld表都包含不同的列,因此它将使一个巨大的表充满空值。如果可以的话,我想避免这种情况。我现在可以想到的是两步解决方案。创建一个包含两列的新表,即
MACHINE\u TYPE
CONCATENATED
所有其他带有分隔符(如逗号)的列。此表将帮助您
连接
。现在对于select,您可以使用内置函数轻松地转换行中的
分隔文本列。子表包含不同类型的列。@Minaverma我确信它们包含不同类型的列,但我不知道这有什么关系。组合子表的问题是每个表包含不同的列集,我不想以mor结束e空值大于填充值。我想我开始得出结论,我需要8个不同的视图,每个视图都包含一组父列和子列……其他方面,我最终会得到很多空值。@JoeMilo这是一个选项,您可以为每种类型创建一个视图,并通过一个
UNION ALL
将它们组合到一个查询中(本质上,这正是我的第二个查询建议所做的)@Siyual我明白你的意思了,但是,我忽略了一点,那就是表的行数都不一样。我刚刚测试了你的代码,在child3中添加了第二列,它不能处理不同的行数,所以我只能查询几个视图,但我真的很喜欢你的代码片段,这是一个非常酷的例子使用并集和联接。