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

SQL Server 2012:含指定日期时获取列中次小日期的查询问题

没问题,我来帮你搞定这个SQL Server 2012的日期筛选需求!首先咱们先把表和测试数据准备好,再一步步实现你要的逻辑。

解决方案:SQL Server 2012 按规则获取行内最小日期

首先创建表并插入测试数据:

-- 创建表t
CREATE TABLE t (
    dt1 date,
    dt2 date,
    dt3 date,
    dt4 date
);

-- 插入测试数据
INSERT INTO t VALUES
('1970-01-01','2008-10-10',NULL,NULL),
(NULL,'2008-10-10','2017-10-12',NULL),
('1970-01-01','2008-10-10',NULL,'2018-10-09');

核心思路

你的需求是对每行的四个日期列,获取最小日期;但如果该行存在'1970-01-01',则排除这个值后取最小(也就是第二小的日期)。直接对列操作会比较繁琐,我们可以先把每行的多个日期列转换为多行(行转列),这样就能更灵活地筛选和排序日期。

实现方案(推荐)

这里用CROSS APPLY实现行转列,结合聚合函数和条件判断来得到目标日期:

SELECT 
    -- 保留原表所有列
    t.dt1, t.dt2, t.dt3, t.dt4,
    -- 根据规则计算目标日期
    CASE 
        -- 判断当前行是否存在'1970-01-01'
        WHEN MAX(CASE WHEN ud.dt = '1970-01-01' THEN 1 ELSE 0 END) = 1
        -- 存在则排除该值后取最小日期
        THEN MIN(CASE WHEN ud.dt <> '1970-01-01' THEN ud.dt END)
        -- 不存在则直接取最小日期
        ELSE MIN(ud.dt)
    END AS target_min_date
FROM t
-- 将四个日期列转为多行,同时过滤NULL值
CROSS APPLY (
    VALUES (dt1), (dt2), (dt3), (dt4)
) unpivoted_dates(dt)
WHERE unpivoted_dates.dt IS NOT NULL
-- 按原表的行分组
GROUP BY t.dt1, t.dt2, t.dt3, t.dt4;

方案解释

  1. 行转列:通过CROSS APPLY配合VALUES,把每行的四个日期列拆成单独的行,同时用WHERE过滤掉NULL值,避免干扰计算。
  2. 条件判断:用MAX(CASE...)判断当前行是否包含'1970-01-01'——如果存在,这个值会返回1,否则0。
  3. 计算目标日期:如果存在'1970-01-01',就用MIN(CASE...)排除该值后取最小日期;否则直接取所有日期的最小值。

测试结果

执行上面的SQL后,会得到如下结果:

dt1dt2dt3dt4target_min_date
1970-01-012008-10-10NULLNULL2008-10-10
NULL2008-10-102017-10-12NULL2008-10-10
1970-01-012008-10-10NULL2018-10-092008-10-10

完全符合你的需求:第一行和第三行因为存在'1970-01-01',取了第二小的日期;第二行没有该值,直接取最小日期。

内容的提问来源于stack exchange,提问作者GI.JOE

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 04:27:22