如何使用 Left Join 和子查询修复 SQL 查询?

How to fix SQL query with Left Join and subquery?

我有 SQL 使用 LEFT JOIN 的查询:

SELECT COUNT(stn.stocksId) AS count_stocks
FROM MedicalFacilities AS a
LEFT JOIN stocks stn ON 
(stn.stocksIdMF = ( SELECT b.MedicalFacilitiesIdUser 
                        FROM medicalfacilities AS b 
                        WHERE b.MedicalFacilitiesIdUser = a.MedicalFacilitiesIdUser 
                        ORDER BY stn.stocksId DESC LIMIT 1) 

AND stn.stocksEndDate >= UNIX_TIMESTAMP() AND stn.stocksStartDate <= UNIX_TIMESTAMP())

这些查询我想 select 从 table stocks 的一行按条件和字段等于 a.MedicalFacilitiesIdUser.

我总是得到 count_stocks = 0 结果。但是我需要得到 1

count(...) 聚合不计算 null,因此它的参数很重要:

COUNT(stn.stocksId)

因为 stn 是你的右手 table,如果 left join 未命中,这将不算数。您可以使用:

COUNT(*)

计算每一行,即使它的所有列都是 null。或者左边的列 table (a) 永远不会 null:

COUNT(a.ID)

你在 on 中的子查询对我来说很奇怪:

on stn.stocksIdMF = ( SELECT b.MedicalFacilitiesIdUser 
                      FROM medicalfacilities AS b 
                      WHERE b.MedicalFacilitiesIdUser = a.MedicalFacilitiesIdUser 
                      ORDER BY stn.stocksId DESC LIMIT 1) 

这是比较 MedicalFacilitiesIdUserstocksIdMF。诚然,您没有示例数据或数据布局,但列的命名表明它们不是同一回事。也许你打算:

on stn.stocksIdMF = ( SELECT b.stocksId 
-----------------------------^
                      FROM medicalfacilities AS b 
                      WHERE b.MedicalFacilitiesIdUser = a.MedicalFacilitiesIdUser 
                      ORDER BY b.stocksId DESC
                      LIMIT 1) 

此外,按 stn.stocksid 排序不会做任何有用的事情,因为那将来自 外部 子查询。

您的子查询似乎多余,而且主查询难以阅读,因为大部分连接语句都可以放在 where 子句中。此外,原始查询可能存在性能问题。

回想一下 WHERE 是隐式连接,JOIN 是显式连接。查询优化器 如果它们使用相同的表达式,则两者之间没有区别,但可读性和可维护性是另一回事。

考虑修改版本(注意我加了一个GROUP BY):

SELECT COUNT(stn.stocksId) AS count_stocks 
FROM MedicalFacilities AS a 
LEFT JOIN stocks stn ON stn.stocksIdMF = a.MedicalFacilitiesIdUser
WHERE stn.stocksEndDate >= UNIX_TIMESTAMP() 
  AND stn.stocksStartDate <= UNIX_TIMESTAMP()
GROUP BY stn.stocksId
ORDER BY stn.stocksId DESC
LIMIT 1