如何编写SQL查询获取指定个数唯一日期值对应的所有行?
按唯一字段值数量筛选表行的SQL实现方案
核心需求为筛选表数据,让返回结果里的唯一date字段值数量等于指定阈值,典型场景是取最近N天的全量业务记录,以下是可直接落地的语法方案:
方案1:通用窗口函数写法(兼容绝大多数现代数据库)
适用于MySQL 8.0+、PostgreSQL、SQL Server、Hive、Spark SQL等所有支持窗口函数的数据库环境,逻辑稳定可扩展性强。
-- 示例:取按日期升序排列的前3个唯一日期对应的所有记录 WITH sorted_unique_date AS ( SELECT date, -- 给去重后的日期按排序规则打连续序号 DENSE_RANK() OVER (ORDER BY date ASC) AS date_seq FROM 你的业务表名 GROUP BY date ) SELECT t.* FROM 你的业务表名 t INNER JOIN sorted_unique_date d ON t.date = d.date WHERE d.date_seq <= 3; -- 此处3为你设置的唯一日期数量阈值
如果是取最近N天的场景,只需要把窗口函数里的排序规则改成ORDER BY date DESC即可,其余逻辑不用调整。
这个写法完全匹配给出的示例逻辑:示例数据去重后升序排列的日期依次为1/2/2022(序号1)、2/2/2022(序号2)、3/2/2022(序号3)、4/2/2022(序号4),筛选序号<=3的日期关联原表,正好返回预期的4条结果。
方案2:老版本数据库兼容写法
针对不支持CTE、窗口函数的低版本MySQL等环境,可以用子查询关联的方式实现,逻辑更简单:
SELECT t.* FROM 你的业务表名 t INNER JOIN ( SELECT date FROM 你的业务表名 GROUP BY date -- 先对日期去重 ORDER BY date ASC LIMIT 3 -- 此处填唯一日期数量阈值 ) AS target_date ON t.date = target_date.date;
注意事项
- 不要直接对原表写
LIMIT 行数做筛选:同一天可能对应多条业务记录,直接截行数会出现还没凑够指定数量的唯一日期,数据就被截断的问题 - 如果存的是带时分秒的datetime类型字段,先通过日期函数截取纯日期部分再做分组、排序、关联,避免同一自然日因为时分秒差异被判定为不同的日期值
内容的提问来源于stack exchange,提问作者Shreyas Jadhav
相关产品推荐
相关产品推荐

