SQL查询构建:获取无黑色家具及无黑色桌子的房屋(无中子查询)
没问题,我结合你的表结构来帮你写出这两个查询,尽量清晰易懂:
问题1:查询没有黑色家具的房屋
要找出所有不存在任何黑色家具的房屋(包括完全没有摆放家具的房屋),可以用分组统计的方式来实现:
SELECT h.Name FROM house h LEFT JOIN house_furniture hf ON h.id = hf.HouseID LEFT JOIN furniture f ON hf.FurnitureID = f.id GROUP BY h.id, h.Name HAVING COUNT(CASE WHEN f.Color = '黑色' THEN 1 END) = 0;
思路说明:
- 用
LEFT JOIN保证所有房屋都被纳入结果,哪怕它没有关联任何家具。 CASE WHEN语句会为每个黑色家具标记1,其他情况为NULL,COUNT只会统计非NULL的值。HAVING子句过滤掉那些有至少一件黑色家具的房屋,剩下的就是完全没有黑色家具的房屋。
问题2:查询没有黑色桌子的房屋(不使用子查询)
要求不能用子查询的话,我推荐两种兼容性不错的写法:
写法一:左连接筛选法
SELECT DISTINCT h.Name FROM house h LEFT JOIN house_furniture hf ON h.id = hf.HouseID LEFT JOIN furniture f ON hf.FurnitureID = f.id AND f.Name = '桌子' AND f.Color = '黑色' WHERE f.id IS NULL;
思路说明:
- 这里把“黑色桌子”的条件直接写在
LEFT JOIN的关联条件里,只尝试匹配房屋关联的黑色桌子。 - 如果房屋没有任何黑色桌子(包括没家具、有家具但没有黑色桌子的情况),
f.id会是NULL,通过WHERE子句筛选出这些记录。 DISTINCT用来避免同一个房屋因为关联多个非黑色家具而被重复返回。
写法二:EXCEPT排除法(适用于支持该语法的数据库,如PostgreSQL、SQL Server)
SELECT h.Name FROM house h EXCEPT SELECT h.Name FROM house h JOIN house_furniture hf ON h.id = hf.HouseID JOIN furniture f ON hf.FurnitureID = f.id WHERE f.Name = '桌子' AND f.Color = '黑色';
思路说明:
- 先获取所有房屋的名称,再减去那些关联了黑色桌子的房屋名称,剩下的就是符合要求的结果。
- 逻辑非常直观,而且完全没有使用子查询。
内容的提问来源于stack exchange,提问作者VadRsa
相关产品推荐
相关产品推荐

