You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在SQL查询指定日期范围数据时额外返回前后各一条填充数据

高效实现方案

只要你为DATETIME列建立了索引,下面的方案比你原本三次查询再合并的性能更高,全程走索引无全表扫描,也不需要应用层做额外的结果拼接:

SELECT * FROM MYTABLE 
WHERE [DATETIME] >= '2018/01/01 03:00' AND [DATETIME] < '2018/01/01 11:00'

UNION ALL

-- 取范围之前最近的1条
SELECT * FROM MYTABLE
WHERE [DATETIME] < '2018/01/01 03:00'
ORDER BY [DATETIME] DESC
LIMIT 1

UNION ALL

-- 取范围之后最近的1条
SELECT * FROM MYTABLE
WHERE [DATETIME] >= '2018/01/01 11:00'
ORDER BY [DATETIME] ASC
LIMIT 1

-- 可选:如果需要结果按时间升序排列,加上这行
ORDER BY [DATETIME] ASC

不同数据库的取前1条语法有差异,按需调整即可:

  • SQL Server 把LIMIT 1替换为TOP 1,写在SELECT关键字之后
  • Oracle 把LIMIT 1替换为FETCH FIRST 1 ROW ONLY,写在对应子句的ORDER BY之后

如果你用的是支持窗口函数的数据库版本(MySQL 8.0+/PostgreSQL/SQL Server 2012+/Oracle),需要后续扩展逻辑比如取前后各N条的话,可以用窗口函数写法,逻辑更统一:

WITH range_tag AS (
    SELECT *,
        CASE 
            WHEN [DATETIME] >= '2018/01/01 03:00' AND [DATETIME] < '2018/01/01 11:00' THEN 1
            WHEN [DATETIME] < '2018/01/01 03:00' THEN 2
            ELSE 3 
        END AS range_type
    FROM MYTABLE
),
ranked_data AS (
    SELECT *,
        ROW_NUMBER() OVER(
            PARTITION BY range_type 
            ORDER BY 
                CASE WHEN range_type=2 THEN [DATETIME] END DESC,
                CASE WHEN range_type=3 THEN [DATETIME] END ASC
        ) AS rn
    FROM range_tag
)
SELECT * FROM ranked_data
WHERE range_type=1 OR (range_type IN (2,3) AND rn=1)
ORDER BY [DATETIME] ASC

内容的提问来源于stack exchange,提问作者UndeadEmo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 13:36:01