技术问询:查找同时拥有战列舰(bb)和战列巡洋舰(bc)的国家
解决思路:查找同时拥有战列舰(bb)和战列巡洋舰(bc)的国家
嘿,我明白你为啥头疼了——用简单的AND根本查不出结果,毕竟一条记录里的舰船类型只能是bb或者bc,不可能同时满足俩条件嘛!先理清楚你的数据集:
| 序号 | 国家 | 舰船类型 |
|---|---|---|
| 1 | 德国 | bb |
| 2 | 美国 | bb |
| 3 | 日本 | bc |
| 4 | 美国 | bb |
| 5 | 英国 | bc |
| 6 | 英国 | bb |
| 7 | 美国 | bb |
| 8 | 荷兰 | bc |
| 9 | 日本 | bb |
为什么简单AND不生效?
WHERE 舰船类型 = 'bb' AND 舰船类型 = 'bc'这个条件逻辑矛盾:它要求单条记录同时属于两种舰船类型,而你的数据里每条记录只有一种类型,自然查不到任何结果。
下面给你三个实用的解决方法:
方法1:分组统计+
HAVING子句
这是最直观的方法,先筛选出仅包含bb和bc的记录,按国家分组后,检查该国家是否拥有两种不同的舰船类型:SELECT 国家 FROM 你的表名 WHERE 舰船类型 IN ('bb', 'bc') GROUP BY 国家 HAVING COUNT(DISTINCT 舰船类型) = 2;解释:
COUNT(DISTINCT 舰船类型)会统计每个国家的不同舰船类型数量,等于2就说明同时拥有bb和bc。方法2:自连接查询
将表和自身连接,分别匹配拥有bb和bc的国家,取交集:SELECT DISTINCT a.国家 FROM 你的表名 a JOIN 你的表名 b ON a.国家 = b.国家 WHERE a.舰船类型 = 'bb' AND b.舰船类型 = 'bc';解释:
a表筛选出有战列舰的国家,b表筛选出有战列巡洋舰的国家,通过国家字段连接后,就能得到同时满足两种条件的国家,DISTINCT用来去重。方法3:子查询+
EXISTS
先找到所有拥有bb的国家,再逐个检查这些国家是否存在bc类型的记录:SELECT DISTINCT 国家 FROM 你的表名 t1 WHERE 舰船类型 = 'bb' AND EXISTS ( SELECT 1 FROM 你的表名 t2 WHERE t2.国家 = t1.国家 AND t2.舰船类型 = 'bc' );解释:
EXISTS会高效判断子查询是否有结果,只要某个国家同时存在bb和bc的记录,就会被筛选出来。
内容的提问来源于stack exchange,提问作者NickW
相关产品推荐
相关产品推荐

