包含3个联接表的SQL select语句

包含3个联接表的SQL select语句,sql,join,Sql,Join,我有三个表blocksequencesblocksequencepartspartpositions 以下分别是一些示例: blocksequenceid P1 P2 P3 P4 E006-T001-S054-S036 E006 T001 S054 S036 blocksequenceid partid E006-T001-S054-S036 E006 E006-T001-S054-S036 T001 E006-T001-S054-S036 S054 E006-T001-S054-S036 S

我有三个表
blocksequences
blocksequenceparts
partpositions
以下分别是一些示例:

blocksequenceid P1 P2 P3 P4
E006-T001-S054-S036 E006 T001 S054 S036

blocksequenceid partid
E006-T001-S054-S036 E006
E006-T001-S054-S036 T001
E006-T001-S054-S036 S054
E006-T001-S054-S036 S036

partpositions
E006 P1
T001 P2
S054 P3
S054 P4
S036 P3
S036 P4
如您所见,S054和S036可以位于位置P3或P4(在不同的块序列中可以看到)

我要创建此表:

blocksequenceid partid positionid
E006-T001-S054-S036 E006 P1
E006-T001-S054-S036 T001 P2
E006-T001-S054-S036 S054 P3
E006-T001-S054-S036 S036 P4
但是相反,我得到了

blocksequenceid partid positionid
E006-T001-S054-S036 E006 P1
E006-T001-S054-S036 T001 P2
E006-T001-S054-S036 S054 P3
E006-T001-S054-S036 S054 P4
E006-T001-S054-S036 S036 P3
E006-T001-S054-S036 S036 P4
因此,对于这个特定的区块序列,S054位于位置P3,S036仅位于位置P4,但我得到了这些零件的所有可能位置,而与区块序列无关

这是我一直在使用的声明:

create table test as( 
select blocksequenceparts.blocksequenceid, blocksequenceparts.partid, partpositions.positionid
from blocksequences right outer join blocksequenceparts on blocksequences.blocksequenceid=blocksequenceparts.blocksequenceid  left outer join partpositions on blocksequenceparts.partid=partpositions.partid
order by blocksequenceid);

不知道该怎么做才能得到我想要的结果。如果有帮助的话,我愿意改变我的桌子。

你应该如何决定哪一部分放在哪一个位置?您提供的数据分为六行。真正的解决方案是
partpositions
每个零件只有一行,或者
blocksequenceparts
包含位置和零件

此查询无法解决您的问题,但至少可以简化查询:

select bs.blocksequenceid, bsp.partid, pp.positionid
from blocksequences bs left outer join
     blocksequenceparts bsp
     on bs.blocksequenceid = bsp.blocksequenceid  left outer join
     partpositions pp
     on bsp.partid = pp.partid
order by bs.blocksequenceid;
首先,请注意,使用表别名时,查询的编写和读取要容易得多

第二,外部联接的规则

  • 您几乎总是希望
    左连接
    。事实上,我几乎从不使用
    右连接。我从不混合使用
    左连接
    右连接
    ,除非目的是说明一些奇怪的行为
  • 左连接
    很有意义。保留第一个表中的所有行,即使子序列表中没有匹配项
  • 子句(
    where
    groupby
    order by
    )通常应使用第一个表中的列
通过使用聚合,每个序列/零件位置可以获得一行:

select bs.blocksequenceid, max(bsp.partid), pp.positionid
from blocksequences bs left outer join
     blocksequenceparts bsp
     on bs.blocksequenceid = bsp.blocksequenceid  left outer join
     partpositions pp
     on bsp.partid = pp.partid
group by bs.blocksequenceid, pp.positionid
order by bs.blocksequenceid;

这使您几乎无法控制选择哪个partid

在您的示例中,只有partid S054具有多个partpositions。。。如果只有一个partid有多个partposition是真的,那么解决方案就是一个复杂的消去过程。但是,如果多个部件可能位于同一部件位置,则数据中没有足够的信息可供解决。例如,如果S054和E006的PartPositionID都为3和4,则可能存在多个解决方案。。无论如何,这个想法是一些部分可以在多个位置取决于区块序列。那么,我应该向这些表中添加什么才能正确选择呢?您忽略的数据库基本原理是,记录在表中并没有固有的位置。因此,当S054和S036都适用于位置3和4时,没有任何东西可以告诉基于集合的逻辑哪个应该有哪个。现在,如果您的块序列正在到达,您可以添加一个时间戳,用于澄清位置。如果我将列P1、P2、P3、P4添加到我的块序列表中,其中P1将是E006,P2将是T001,P3将是S054,P4将是S036。。我现在可以使用该表为该部分选择正确的位置吗?第二条语句有助于删除重复项,但现在我得到:P3和P4的S054当我想要P4的S036时,基本上我确信我需要在表中添加一些列,缺少一些信息。我如何告诉数据库,对于此块序列,此零件处于此位置?我应该将P1 P2 P3 P4列添加到blocksequences表中,还是只将列positionid添加到blocksequenceparts表中更好?然后我将如何选择?您需要将位置添加到
blocksequenceparts
,以便可以在两个键上进行连接。