我有LEFT JOIN的SQL查询:
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())
这些查询我希望按条件选择表stocks
中的一行,并使用字段等值a.MedicalFacilitiesIdUser
。
我的结果总是count_stocks = 0
。但我需要1
答案 0 :(得分:2)
count(...)
汇总并不算null
,因此其论点很重要:
COUNT(stn.stocksId)
由于stn
是您的右手表,如果left join
未命中,则不计算任何内容。你可以使用:
COUNT(*)
计算每一行,即使其所有列都是null
。或左侧表格中的一列(a
)从不null
:
COUNT(a.ID)
答案 1 :(得分:1)
on
中的子查询对我来说很奇怪:
on stn.stocksIdMF = ( SELECT b.MedicalFacilitiesIdUser
FROM medicalfacilities AS b
WHERE b.MedicalFacilitiesIdUser = a.MedicalFacilitiesIdUser
ORDER BY stn.stocksId DESC LIMIT 1)
这是将MedicalFacilitiesIdUser
与stocksIdMF
进行比较。不可否认,您没有样本数据或数据布局,但列的命名表明这些并不相同。也许你打算:
on stn.stocksIdMF = ( SELECT b.stocksId
-----------------------------^
FROM medicalfacilities AS b
WHERE b.MedicalFacilitiesIdUser = a.MedicalFacilitiesIdUser
ORDER BY b.stocksId DESC
LIMIT 1)
另外,按stn.stocksid
排序不会做任何有用的事情,因为那将来自在子查询中。
答案 2 :(得分:0)
您的子查询似乎是多余的,主查询很难阅读,因为很多连接语句都可以放在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