SQL中如何筛选家庭首次捐赠记录并统计各捐赠项目唯一家庭数
嘿,这个需求其实挺典型的——核心就是要定位到每个家庭针对单个捐赠项目的首次捐赠记录,再基于这些记录统计每个项目对应的独特家庭数量。不过这里有个关键前提:你的表得有一个能判断捐赠先后顺序的字段,比如DonationDate(捐赠日期)或者RecordCreatedAt(记录生成时间),毕竟得知道哪条是“首次”嘛。如果没有日期,那至少要有个自增的记录ID(比如DonationRecordID),用ID大小来推断先后也可以。
下面给你两种常用的SQL实现方案,适配不同的数据库版本:
方案一:用窗口函数(推荐,适用于PostgreSQL、MySQL 8+、SQL Server等)
窗口函数是处理这类分组排序问题的利器,写法简洁且性能不错:
-- 先筛选出每个家庭对每个捐赠项目的首次捐赠记录 WITH FirstDonations AS ( SELECT HouseholdID, DonationID, -- 按家庭+捐赠项目分组,每组内按日期升序排,首次捐赠的行号为1 ROW_NUMBER() OVER (PARTITION BY HouseholdID, DonationID ORDER BY DonationDate ASC) AS rn FROM your_table_name -- 替换成你的实际表名 ) -- 统计每个捐赠项目对应的唯一家庭数 SELECT DonationID, COUNT(DISTINCT HouseholdID) AS UniqueHouseholdCount FROM FirstDonations WHERE rn = 1 GROUP BY DonationID;
简单解释:
PARTITION BY HouseholdID, DonationID:把数据拆成「每个家庭+每个捐赠项目」的小组ORDER BY DonationDate ASC:确保每个小组里最早的捐赠排在最前面ROW_NUMBER():给每个小组的行按顺序编号,首次捐赠的行号就是1- 最后筛选出行号为1的记录,再按
DonationID分组统计家庭数量就搞定了。
方案二:用GROUP BY + 关联查询(适配老版本数据库,比如MySQL 5.x)
如果你的数据库不支持窗口函数,那就用传统的分组+关联方式:
SELECT t1.DonationID, COUNT(DISTINCT t1.HouseholdID) AS UniqueHouseholdCount FROM your_table_name t1 INNER JOIN ( -- 先找出每个家庭对每个捐赠项目的最早捐赠日期 SELECT HouseholdID, DonationID, MIN(DonationDate) AS FirstDonationDate FROM your_table_name GROUP BY HouseholdID, DonationID ) t2 ON t1.HouseholdID = t2.HouseholdID AND t1.DonationID = t2.DonationID AND t1.DonationDate = t2.FirstDonationDate GROUP BY t1.DonationID;
简单解释:
- 子查询先按「家庭+捐赠项目」分组,取出每组的最早捐赠日期
- 再用这个子查询的结果关联原表,找到对应的首次捐赠记录
- 最后按捐赠项目分组统计家庭数即可。
如果你的表没有日期字段,把上面的DonationDate换成自增的记录ID(比如DonationRecordID)就好,因为自增ID越小,记录创建时间越早,同样能判断首次。
内容的提问来源于stack exchange,提问作者Ellie Connors
相关产品推荐
相关产品推荐

