能否通过单条SQL查询实现两次分组并获取最新提交的问卷?
当然可以用单条SQL查询实现这个需求!
我来给你两种实用的单条查询方案,覆盖不同场景和数据库支持情况:
方法一:窗口函数(推荐,性能与可读性兼顾)
窗口函数是处理这类「分组取最值」场景的最优解之一。结合你的需求——先按Number分组,再按SurveyName分组取最晚提交记录,本质是要在每个(Number, SurveyName)的组合里筛选出提交日期最新的那条。
具体SQL写法如下:
SELECT * FROM ( SELECT *, -- 按Number+SurveyName分组,组内按提交日期倒序排名 ROW_NUMBER() OVER (PARTITION BY Number, SurveyName ORDER BY submittedDate DESC) AS rank_num FROM Survey ) ranked_surveys -- 取每个分组里排名第一的(也就是提交最晚的)记录 WHERE rank_num = 1;
简单解释下逻辑:
PARTITION BY Number, SurveyName帮你完成「先按Number分组,再按SurveyName分组」的划分,把数据拆成一个个独立的子组。ORDER BY submittedDate DESC让每个子组内的记录从最新提交到最早提交排序。- 外层筛选
rank_num=1,就拿到了每个子组里提交日期最晚的问卷记录。
如果你的真实需求是忽略Number,只按SurveyName分组取全表中该问卷名称的最晚提交记录,只需调整PARTITION BY的字段:
SELECT * FROM ( SELECT *, ROW_NUMBER() OVER (PARTITION BY SurveyName ORDER BY submittedDate DESC) AS rank_num FROM Survey ) ranked_surveys WHERE rank_num = 1;
方法二:关联子查询(兼容老版本数据库)
如果你的数据库不支持窗口函数(比如早期版本的MySQL),可以用关联子查询实现相同效果:
SELECT s.* FROM Survey s WHERE submittedDate = ( -- 子查询找到当前记录所属Number+SurveyName组的最大提交日期 SELECT MAX(submittedDate) FROM Survey WHERE Number = s.Number AND SurveyName = s.SurveyName );
这个写法的逻辑是:逐条检查Survey表的记录,只保留那些提交日期等于自身所属(Number, SurveyName)组内最大提交日期的条目,也就是每组的最晚提交记录。
小提示:如果同一个分组里有多条记录提交日期相同且都是最晚的,关联子查询会返回所有这些并列的记录;而窗口函数用
ROW_NUMBER()只会返回其中一条,若要保留所有并列项,可以换成RANK()函数。
内容的提问来源于stack exchange,提问作者user9480778
相关产品推荐
相关产品推荐

