获取各NBHD分组下40条最新销售记录的MS Access SQL需求
解决方案:MS Access SQL实现分组取最新记录并去重
嘿,这个需求我之前处理过类似的,MS Access的SQL语法和标准SQL有不少差异,得用针对性的写法来实现。下面给你两种方案,分别适配不同版本的Access:
方案一:兼容所有Access版本(嵌套子查询写法)
这种写法不用依赖窗口函数,老版本Access也能跑通:
SELECT s.* FROM Sales s INNER JOIN ( -- 先给每个PARID保留其在NBHD前40条里的最新销售日期 SELECT PARID, MAX(SALEDT) AS LatestSaleDT FROM ( -- 按区域分组,取每个NBHD的前40条最新销售记录 SELECT TOP 40 PARID, SALEDT, NBHD FROM Sales ORDER BY NBHD, SALEDT DESC ) AS Top40PerNBHD GROUP BY PARID, NBHD ) AS LatestPerPARID ON s.PARID = LatestPerPARID.PARID AND s.SALEDT = LatestPerPARID.LatestSaleDT ORDER BY s.NBHD, s.SALEDT DESC;
代码逻辑拆解
- 最内层子查询
Top40PerNBHD:通过ORDER BY NBHD, SALEDT DESC先按区域分组,再按销售日期倒序排列,用TOP 40提取每个区域的前40条最新销售记录。这里要注意ORDER BY的顺序,必须先写NBHD才能确保是按区域分组取数。 - 中间层子查询
LatestPerPARID:对上面的前40条记录,按PARID和NBHD分组,用MAX(SALEDT)获取每个房产的最新销售日期,这样就自动去掉了同一PARID的重复记录,只保留该房产在当前区域前40条里的最新那条。 - 最外层查询:把原表和中间层结果通过
PARID和SALEDT关联,拿到这些去重后的记录的完整字段数据,最后再按区域和销售日期倒序排列,方便查看结果。
方案二:适合Access 2019/365版本(窗口函数写法)
如果你的Access是2019及以后或者365版本,支持窗口函数,那写法会更简洁直观:
SELECT PARID, PRICE, SALEDT, SALEVAL, NBHD FROM ( SELECT *, -- 给每个NBHD内的记录按销售日期倒序排名,取前40 ROW_NUMBER() OVER (PARTITION BY NBHD ORDER BY SALEDT DESC) AS RN_NBHD, -- 给每个PARID内的记录按销售日期倒序排名,取最新的那条(排名1) ROW_NUMBER() OVER (PARTITION BY PARID ORDER BY SALEDT DESC) AS RN_PARID FROM Sales ) AS RankedSales WHERE RN_NBHD <= 40 AND RN_PARID = 1 ORDER BY NBHD, SALEDT DESC;
代码逻辑拆解
- 用
ROW_NUMBER()窗口函数生成两条排名:RN_NBHD:按NBHD分区,每个区域内的记录按SALEDT倒序排,排名<=40的就是每个区域的前40条最新记录。RN_PARID:按PARID分区,每个房产的记录按SALEDT倒序排,排名=1的就是该房产的最新销售记录。
- 最后通过
WHERE条件同时筛选这两个排名,一步到位得到符合要求的结果,比嵌套子查询更易读和维护。
内容的提问来源于stack exchange,提问作者Jsqsh
相关产品推荐
相关产品推荐

