微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

从一张表中的几个日期时间列中查找最早的非空日期时间

如何解决从一张表中的几个日期时间列中查找最早的非空日期时间

我的数据库 (sql Server 2012) 中有一个表,其中包含多个日期时间字段。假设所有字段都可以为空。我试图找到每一行存在的最早的非 NULL 日期。

我尝试的解决方案是使用可怕的 CASE 表达式:

--To return the earliest non-NULL time that exists from table tmp
--Datetime fields are dt_lab_instrument,dt_lab_scan,dt_arrived,dt_receipted

SELECT
    CASE
        WHEN tmp.dt_lab_instrument IS NOT NULL AND tmp.dt_lab_instrument <= tmp.dt_lab_scan AND tmp.dt_lab_instrument <= tmp.dt_arrived AND tmp.dt_lab_instrument <= tmp.dt_receipted THEN tmp.dt_lab_instrument
        WHEN tmp.dt_lab_scan IS NOT NULL AND tmp.dt_lab_scan <= tmp.dt_lab_instrument AND tmp.dt_lab_scan <= tmp.dt_arrived AND tmp.dt_lab_scan <= tmp.dt_receipted THEN tmp.dt_lab_scan
        WHEN tmp.dt_arrived IS NOT NULL AND tmp.dt_arrived <= tmp.dt_lab_instrument AND tmp.dt_arrived <= tmp.dt_lab_scan AND tmp.dt_arrived <= tmp.dt_receipted THEN tmp.dt_arrived
        WHEN tmp.dt_receipted IS NOT NULL AND tmp.dt_receipted <= tmp.dt_lab_instrument AND tmp.dt_receipted <= tmp.dt_lab_scan AND tmp.dt_receipted <= tmp.dt_arrived THEN tmp.dt_receipted
        ELSE '1990-01-01' --If all else fails return dummy date value
    END
from tmp

这是丑陋的、低效的、不处理空值、难以扩展(即尝试添加更多的日期字段!)而且似乎是错误的。但我似乎对如何更好地解决这个问题有一个心理障碍。

我知道我可以通过使用 ISNULL 函数将任何 NULL 日期时间值替换为遥远未来的日期来处理空值,但这似乎只会让丑陋的代码变得更加丑陋。

请有人帮助我以更好、更有效的方式解决这个问题吗?提前致谢

解决方法

使用 VALUES() 运算符将日期列反透视为行并使用 MIN() 查找最早的

select *
from   tmp t
       cross apply
       (
           select min(dt) as min_dt
           from
           (
               values (dt_lab_instrument),(dt_lab_scan),(dt_arrived),(dt_receipted)
           ) m (dt)
       ) m

处理If all else fails return dummy date value,可以使用

ISNULL(min(dt),'1990-01-01')

COALESCE(min(dt),'1990-01-01')

,

如果我猜对了,你想获得这 4 个字段中最早的

dt_lab_instrument
dt_lab_scan
dt_arrived
dt_receipted

因此,您可以使用 MIN() 函数从此字段中选择所有最小值,然后从此字段中选择最小值

SELECT MIN(C)
    FROM (VALUES 
    (SELECT MIN(dt_lab_instrument) from tmp where dt_lab_instrument is not null),(SELECT MIN(dt_lab_scan) from tmp where dt_lab_instrument is not null),(SELECT MIN(dt_arrived) from tmp where dt_lab_instrument is not null),(SELECT MIN(dt_receipted) from tmp where dt_lab_instrument is not null) 
    AS v (C)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。