MySQL使用子查询加入,只从连接表中选择一行

时间:2012-11-01 18:20:06

标签: mysql join subquery

假设有两个表:

表部分:

Location PartNum Descrip  
-------- ------- --------
Whse1    abc     Frobbitz
Whse2    abc     Frobbitz
Whse3    def     Widget
Whse3    def     Widget

表状态:

Location  PartNum Status
--------- ------- --------------
*Default* abc     Ready To Ship
*Default* def     Ready To Ship
Whse1     abc     Backordered

在大多数情况下,应使用默认状态。

要获取状态,查询可能如下所示:

SELECT p.Location,p.PartNum,p.Descrip,s.Status FROM Parts p
LEFT JOIN Status s ON s.PartNum=p.PartNum AND
s.Location = (SELECT MAX(Location) FROM Status s1
WHERE s1.PartNum=p.PartNum AND s1.Location
IN('*Default*',p.Location))

问题是,这是最有效(或至少是合理有效)的方式吗?我的实际应用程序最多可以在一个查询中加入7个表。

3 个答案:

答案 0 :(得分:0)

我认为您可以将Limit 1与Order by一起使用,如下所示:

 SELECT p.Location,p.PartNum,p.Descrip,s.Status FROM Parts p
  LEFT JOIN Status s ON s.PartNum=p.PartNum AND
  s.Location = (SELECT Location FROM Status s1
        WHERE s1.PartNum=p.PartNum ORDER BY s1.Location ASC LIMIT 1);

假设*Default*将通过检索按顺序排在最前面。

答案 1 :(得分:0)

SELECT p.Location,p.PartNum,p.Descrip,s.Status FROM Parts p
LEFT outer JOIN Status s ON s.PartNum=p.PartNum 
where
s.Location = (SELECT MAX(Location) FROM Status s1
WHERE s1.PartNum=p.PartNum AND s1.Location
IN('*Default*',p.Location))

答案 2 :(得分:0)

您尝试执行的操作似乎是使用后备默认值。您可以尝试两次加入表而不是使用子查询:

SELECT p.Location,p.PartNum,p.Descrip,s.Status 
FROM Parts p 
LEFT JOIN Status s1 ON s1.PartNum=p.PartNum AND p.Location = s1.Location 
LEFT JOIN Status s ON p.PartNum = s.PartNum 
   AND s.Location = IFNULL(s1.Location, '*Default*');

基本上,s1表示非默认信息。通过检查s1.Location是否为NULL,我们可以判断这一行是否存在,如果不存在则回退到*Default*

希望有所帮助!