简体   繁体   English

MySQL连接与子查询从连接表中仅选择一行

[英]MySQL Join with a subquery to select only one row from joined table

Suppose there are two tables: 假设有两个表:

Table Parts: 桌子零件:

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

Table Status: 表格状态:

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

In most cases, the default status should be used. 在大多数情况下,应使用默认状态。

To get the status, the query might look like: 要获取状态,查询可能类似于:

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))

The question is, is this the most efficient (or at least reasonably efficient) way of doing this? 问题是,这是最有效(或至少合理有效)的方式吗? My actual application will have up to 7 tables joined in a single query. 我的实际应用程序将在单个查询中加入多达7个表。

I think you can use Limit 1 with Order by as below: 我认为您可以将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);

Assuming *Default* will come at the top in order by retrieval. 假设*Default*将按检索顺序排在最前面。

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))

It appears like what you are trying to do is use a fallback default. 看来您要执行的操作是使用后备默认设置。 You could try something like joining the table twice instead of using a subquery: 您可以尝试类似两次连接表的方法,而不是使用子查询:

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*');

Essentially, s1 represents the non-default information. 本质上, s1代表非默认信息。 By checking whether s1.Location is NULL or not, we can tell if such a row exists and fallback to *Default* if it doesn't. 通过检查s1.Location是否为NULL ,我们可以判断该行是否存在,如果不存在,则回s1.Location *Default*

Hope that helps! 希望有帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM