如何用LEFT JOIN替代MySQL不支持的EXCEPT语句?
用LEFT JOIN替代MySQL的EXCEPT实现“仅售卖台式机的厂商”查询
首先要指出:你原来的EXCEPT查询逻辑是反的——原查询是**(卖笔记本的厂商) EXCEPT (卖台式的厂商),得到的是只卖笔记本的厂商,但你的需求是找出仅售卖台式机的厂商**,正确的EXCEPT逻辑应该是反过来的。不过MySQL不支持EXCEPT,下面是用LEFT JOIN的实现方案:
LEFT JOIN实现代码
SELECT DISTINCT cm_desktop.ManufacturerID FROM ComputerManufacturers cm_desktop INNER JOIN Computers c_desktop ON cm_desktop.ComputerID = c_desktop.ID AND c_desktop.IsLaptop = 0 -- 先筛选出所有售卖台式机的厂商关联记录 LEFT JOIN ComputerManufacturers cm_laptop ON cm_desktop.ManufacturerID = cm_laptop.ManufacturerID LEFT JOIN Computers c_laptop ON cm_laptop.ComputerID = c_laptop.ID AND c_laptop.IsLaptop = 1 -- 关联该厂商售卖笔记本的记录 WHERE c_laptop.ID IS NULL; -- 筛选出没有售卖笔记本的厂商
逻辑解释
- 先通过
INNER JOIN筛选出所有和台式机关联的厂商记录; - 用
LEFT JOIN关联同一厂商的笔记本售卖记录——如果厂商没卖过笔记本,这部分关联结果会是NULL; - 最后通过
WHERE c_laptop.ID IS NULL过滤出那些没有笔记本售卖记录的厂商,也就是仅卖台式机的厂商。
更简洁的替代方案(GROUP BY + HAVING)
除了LEFT JOIN,还可以用分组统计的方式实现,逻辑更直观:
SELECT cm.ManufacturerID FROM ComputerManufacturers cm INNER JOIN Computers c ON cm.ComputerID = c.ID GROUP BY cm.ManufacturerID HAVING SUM(c.IsLaptop) = 0; -- 统计该厂商售卖的笔记本数量,0表示从未卖过笔记本
验证结果
根据你提供的表数据:
- 厂商1有1台笔记本(IsLaptop=1),SUM结果为1,会被排除;
- 厂商2的所有电脑都是台式机(IsLaptop=0),SUM结果为0,会被保留;
最终返回结果只有厂商ID 2,符合预期。
内容的提问来源于stack exchange,提问作者May Sohatchevzzki
相关产品推荐
相关产品推荐

