如何将同一张表的两个SQL查询结果合并为独立列?以及如何统计患者表中男女患者总数并分别列示?
嘿,很高兴能帮到你!作为一个经常和SQL打交道的人,我来一步步给你拆解这两个问题的解决方案,保证好懂又实用~
这是SQL里很常见的需求,核心思路是把两个查询的结果整合到同一行的不同列中,我给你推荐三种常用方法,其中第一种是最通用高效的:
方法1:条件聚合(最推荐)
用CASE WHEN配合聚合函数(比如SUM或COUNT),可以在一次表扫描中完成两个统计,效率最高。举个例子,假设你要统计patients表中2020年之前和之后出生的患者数,写法如下:
SELECT SUM(CASE WHEN birth_date < '2020-01-01' THEN 1 ELSE 0 END) AS pre_2020_count, SUM(CASE WHEN birth_date >= '2020-01-01' THEN 1 ELSE 0 END) AS post_2020_count FROM patients;
原理很简单:CASE WHEN会根据条件返回1或0,SUM把这些值累加起来,就得到符合对应条件的记录数,两个聚合结果自然就变成了独立的列。
方法2:子查询作为列
如果你的两个查询逻辑比较独立,也可以把每个查询直接作为SELECT语句里的一个子查询,比如:
SELECT (SELECT COUNT(*) FROM patients WHERE birth_date < '2020-01-01') AS pre_2020_count, (SELECT COUNT(*) FROM patients WHERE birth_date >= '2020-01-01') AS post_2020_count;
这种写法直观,但要注意:如果表数据量很大,它会扫描表两次,效率不如条件聚合,所以小表用用没问题,大表更推荐第一种方法。
方法3:自连接(适合复杂场景)
如果是更复杂的查询场景,还可以把两个查询的结果作为临时表,然后通过笛卡尔积连接起来,得到一行两列的结果:
SELECT a.pre_2020_count, b.post_2020_count FROM (SELECT COUNT(*) AS pre_2020_count FROM patients WHERE birth_date < '2020-01-01') a, (SELECT COUNT(*) AS post_2020_count FROM patients WHERE birth_date >= '2020-01-01') b;
这种写法灵活性高,但同样会扫描表两次,简单统计场景下没必要用。
这个其实就是问题1的具体应用,用条件聚合就能完美解决,针对你的patients表结构,直接写:
方案一:用SUM+CASE WHEN
SELECT SUM(CASE WHEN gender = 'M' THEN 1 ELSE 0 END) AS male_count, SUM(CASE WHEN gender = 'F' THEN 1 ELSE 0 END) AS female_count FROM patients;
方案二:用COUNT+CASE WHEN
你也可以用COUNT来实现,因为COUNT会自动忽略NULL值,写法更简洁一点:
SELECT COUNT(CASE WHEN gender = 'M' THEN 1 END) AS male_count, COUNT(CASE WHEN gender = 'F' THEN 1 END) AS female_count FROM patients;
原理是:当gender等于'M'时,CASE返回1,否则返回NULL,COUNT只会统计非NULL的数量,这样就得到了男性患者的总数,女性同理。
额外小技巧
如果担心gender列有NULL或者其他异常值,可以加个总数列验证结果:
SELECT SUM(CASE WHEN gender = 'M' THEN 1 ELSE 0 END) AS male_count, SUM(CASE WHEN gender = 'F' THEN 1 ELSE 0 END) AS female_count, COUNT(*) AS total_count FROM patients;
这样你可以检查male_count + female_count是否等于total_count,确保统计没有遗漏。
内容的提问来源于stack exchange,提问作者Prerna Gupta

