SQL解决方案需求:找出男性患者多于女性的省份(显示完整省名)
问题:找出男性患者数量多于女性的省份名称
需求
显示男性患者数量多于女性患者的省份,仅需展示完整的province_name。
表结构
patient表
| 字段名 | 类型 |
|---|---|
| patient_id | INT |
| first_name | TEXT |
| last_name | TEXT |
| gender | CHAR(1) |
| birth_date | DATE |
| city | TEXT |
| province_id | CHAR(2) |
| allergies | TEXT |
| height | INT |
| weight | INT |
province_names表
| 字段名 | 类型 |
|---|---|
| province_id | CHAR(2) |
| province_name | TEXT |
尝试的错误SQL
select province_name from patients p,province_names pn where p.province_id = pn.province_id and (count(p.province_id) group by p.patient_id having p.gender = 'M' ) > (count(p.province_id) group by p.patient_id having p.gender = 'F')
错误分析
你的SQL存在几个核心问题:
- 不能在
WHERE子句中直接使用聚合函数和GROUP BY,聚合逻辑应放在HAVING子句或子查询中 GROUP BY p.patient_id是按患者ID分组,与按省份统计男女数量的需求不符,需按省份分组- 直接在条件中写两个聚合对比的语法不符合SQL规范,无法被引擎解析
正确的SQL写法
方法一:条件聚合直接筛选
SELECT pn.province_name FROM patients p JOIN province_names pn ON p.province_id = pn.province_id GROUP BY pn.province_id, pn.province_name HAVING COUNT(CASE WHEN p.gender = 'M' THEN 1 END) > COUNT(CASE WHEN p.gender = 'F' THEN 1 END);
方法二:先统计再筛选(可读性更强)
WITH province_gender_stats AS ( SELECT p.province_id, SUM(CASE WHEN p.gender = 'M' THEN 1 ELSE 0 END) AS male_count, SUM(CASE WHEN p.gender = 'F' THEN 1 ELSE 0 END) AS female_count FROM patients p GROUP BY p.province_id ) SELECT pn.province_name FROM province_gender_stats s JOIN province_names pn ON s.province_id = pn.province_id WHERE s.male_count > s.female_count;
两种写法均先按省份统计男女患者数量,再筛选出男性数量多于女性的省份,最后关联省份名称表获取完整名称。
内容的提问来源于stack exchange,提问作者Guruprasad Hegde
相关产品推荐
相关产品推荐

