如何编写SQL查询指定Business下无Orders的Accounts?
解决方案
你的查询存在两个核心问题,导致无法得到预期结果:
- LEFT JOIN 后 WHERE 条件破坏左连接特性:使用
LEFT JOIN Token后在WHERE子句中添加T.business_id = 1,会直接过滤掉没有对应Token记录的Account(因为这类记录的T.business_id为NULL,不满足等于1的条件),相当于把左连接变成了内连接,丢失了目标Business下无Token的Account数据。 - 跨Business订单关联缺失(可选):如果Orders表本身关联到Business,未在子查询中限定Business维度,可能会误排除其他Business下同名Account的订单(虽然你测试时没变化,但这是严谨性问题)。
修正后的查询语句
SELECT DISTINCT A.name FROM Accounts AS A LEFT JOIN `Token` AS T ON T.account_id = A.id AND T.business_id = 1 -- 将Business筛选条件移至JOIN的ON子句,保留左连接的全部结果 WHERE T.business_id IS NOT NULL -- 仅保留属于目标Business的Account AND NOT EXISTS ( SELECT 1 FROM Orders AS O WHERE O.account_id = A.id -- 若Orders表存在business_id字段,建议添加以下条件避免跨Business干扰 -- AND O.business_id = 1 )
更简洁的替代写法(若Account直接关联Business)
根据你描述的“每个Business都有独立的Accounts”,如果Accounts表本身带有business_id字段,完全可以跳过Token表直接查询:
SELECT DISTINCT A.name FROM Accounts AS A WHERE A.business_id = 1 AND NOT EXISTS ( SELECT 1 FROM Orders AS O WHERE O.account_id = A.id )
原查询失效的关键原因
- 原查询中
LEFT JOIN Token后加WHERE条件T.business_id = 1,等价于内连接,丢失了无Token但属于目标Business的Account数据。 - 你在Orders子查询中添加
business_id=1无效果,大概率是因为目标Business下的Account没有跨Business的订单,所以该条件未改变结果,但核心问题仍未解决。
内容的提问来源于stack exchange,提问作者smb
相关产品推荐
相关产品推荐

