C语言转SQL:JOIN关联表及MIN/MAX函数使用求助
关联表并找出筹款最低/最高成员的实现方法
嘿,既然你有C系语言背景,那理解SQL的核心逻辑其实没那么难,咱们一步步来搞定这个找筹款最值成员的问题~
基础解法:子查询 + 表关联
这个方法逻辑直观,适合SQL新手理解:先找到全局的最高/最低筹款额,再关联两张表找出对应的成员。
1. 单独查询最高/最低筹款的成员
如果只想找筹款最高的成员,用这段SQL:
SELECT p.IDNumber, p.FirstName, p.LastName, d.DollarsRaised FROM person p INNER JOIN donations d ON p.IDNumber = d.IDNumber WHERE d.DollarsRaised = (SELECT MAX(DollarsRaised) FROM donations);
把MAX换成MIN,就能得到筹款最低的成员:
SELECT p.IDNumber, p.FirstName, p.LastName, d.DollarsRaised FROM person p INNER JOIN donations d ON p.IDNumber = d.IDNumber WHERE d.DollarsRaised = (SELECT MIN(DollarsRaised) FROM donations);
2. 同时查询最高和最低的成员
如果想把两个结果合并到一起看,用UNION ALL把两个查询的结果拼接起来,还可以加个Status字段区分类型:
-- 筹款最高的成员 SELECT p.IDNumber, p.FirstName, p.LastName, d.DollarsRaised, '最高筹款' AS Status FROM person p INNER JOIN donations d ON p.IDNumber = d.IDNumber WHERE d.DollarsRaised = (SELECT MAX(DollarsRaised) FROM donations) UNION ALL -- 筹款最低的成员 SELECT p.IDNumber, p.FirstName, p.LastName, d.DollarsRaised, '最低筹款' AS Status FROM person p INNER JOIN donations d ON p.IDNumber = d.IDNumber WHERE d.DollarsRaised = (SELECT MIN(DollarsRaised) FROM donations);
关键逻辑说明:
INNER JOIN:把person和donations表通过IDNumber外键关联起来,只保留两边都有匹配记录的行(也就是排除没捐款的成员)。- 子查询
(SELECT MAX(DollarsRaised) FROM donations):先算出所有捐款里的最高金额,再用这个值去筛选对应的成员。 UNION ALL:直接拼接两个查询结果,比UNION更高效(因为不会去重)。
进阶解法:窗口函数(适合复杂场景)
如果需要更灵活的排序或筛选(比如同时处理多种排名),可以用SQL的窗口函数,一次查询就能搞定:
WITH ranked_donations AS ( SELECT p.IDNumber, p.FirstName, p.LastName, d.DollarsRaised, -- 按筹款额降序排名,第一名就是最高筹款 RANK() OVER (ORDER BY d.DollarsRaised DESC) AS rank_high, -- 按筹款额升序排名,第一名就是最低筹款 RANK() OVER (ORDER BY d.DollarsRaised ASC) AS rank_low FROM person p INNER JOIN donations d ON p.IDNumber = d.IDNumber ) SELECT IDNumber, FirstName, LastName, DollarsRaised, CASE WHEN rank_high = 1 THEN '最高筹款' WHEN rank_low = 1 THEN '最低筹款' END AS Status FROM ranked_donations WHERE rank_high = 1 OR rank_low = 1;
关键逻辑说明:
WITH ranked_donations AS (...):创建一个临时的结果集,给每条捐款记录加上“最高排名”和“最低排名”。RANK()窗口函数:自动给筹款额排序并分配排名,如果有多个成员筹款额相同,会给他们相同的排名(比如两个成员都捐了最高额,都会是rank_high=1)。- 最后筛选出排名第一的记录,就能同时得到最高和最低筹款的成员。
注意事项
- 如果有成员没有捐款记录(
donations表中没有对应IDNumber),INNER JOIN会自动排除他们;如果需要包含这些成员,可以换成LEFT JOIN,但要注意他们的DollarsRaised会是NULL,MIN/MAX会忽略这些值。 - 如果
DollarsRaised字段有NULL值,MIN()和MAX()函数会自动忽略这些记录,不影响结果。
内容的提问来源于stack exchange,提问作者RadHatter
相关产品推荐
相关产品推荐

