2017-10-10 97 views
-1

我需要维护一个物料表。每种材料可能有一种或多种替代材料,因此它将在同一张桌子上形成多对多的关系。用户可以通过给定物料的零件号查询替代物。查询来自同一多对多表

我创建了两个表,如下所示。

CREATE TABLE material (
    id int(3) NOT NULL PRIMARY KEY AUTO_INCREMENT, 
    pn varchar(20) NOT NULL UNIQUE 
); 
CREATE TABLE mapping (
    pn_id int(3) NOT NULL, 
    main_pn_id int(3) NOT NULL, 
    PRIMARY KEY (pn_id, main_pn_id) 
); 
ALTER TABLE mapping ADD FOREIGN KEY (pn_id) REFERENCES material (id); 
ALTER TABLE mapping ADD FOREIGN KEY (main_pn_id) REFERENCES material (id); 

我的查询输入始终为pn(材料的零件编号)。这意味着选择命令看起来像这样。

SELECT * FROM material ..... WHERE pn="XXXXX"; 

如果我想找到给定材料的替代品。我需要先通过零件号查询它的ID。然后我使用id来查找pn_id

SELECT pn_id FROM mapping WHERE main_pn_id=$id 

最后,使用pn_id从材料表中查找pn。

我知道可以通过子查询或UNION来获得材质的替代品,但使用子查询和UNION可能会影响查询性能。我的系统可能被数百人使用。

我试图使用JOIN来完成查询,但我仍然无法弄清楚如何在我的情况下使用JOIN查询备选方案。任何人都可以帮助我吗? 谢谢。

+0

样本数据和预期结果将有所帮助。看起来你只需要为主映射连接两次材料,并且一次连接到pn映射。现在,如果你需要遍历一个层次结构;这是一个不同的故事。但你似乎只是要求每个主要部分可以被替代的部分。材料和制图数据有点模糊,因此我不确定SQl的准确性,因此希望看到示例数据的预期结果。 – xQbert

回答

1

为什么不简单连接到材料两次。

注意我在这里使用了左连接,因为我不确定是否所有的材质都在映射表中。

SELECT M1.ID as MainPartID 
    , M1.PN as MainPartNumber 
    , M2.ID as AltPartID 
    , M2.PN as AltPartNum 
FROM material M1 
LEFT JOIN Mapping Map 
on M1.ID = MAP.PN_ID 
LEFT JOIN Material M2 
on M2.ID = MAP.Main_PN_ID 
WHERE M1.PN = 'XXXXX'