sql - 从一个表中的多个日期时间列中查找最早的非 NULL 日期时间
问题描述
我的数据库(SQL Server 2012)中有一个包含多个日期时间字段的表。假设所有字段都可以为空。我试图找到每行存在的最早的非空日期。
我尝试的解决方案是使用看起来很糟糕的 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')
推荐阅读
- python - /admin/products/product/ 关于 slugfield 的 OperationalError
- python - 点击功能不呈现页面
- foreach - Azure 数据工厂:具有 batchCount 和 item() 属性的 foreach 循环
- wpf - 在保持标题行固定的同时向 wpf Grid 添加垂直滚动条
- vba - vba - 添加多个条件:如果在单元格中输入单词#1、#2 等,则为消息框
- php - 如何在输入一个值中获取我选择的所有数据?
- mongodb - 带有选项 --uri 的 mongoexport / mongodump
- winapi - MFC:CDockablePane 是否收到 CTreeCtrl 的 ON_NOTIFY_REFLECT 消息?
- javascript - 如何比较 Typescript 中的两个列表?
- d3.js - 如何修复返回的节点的配置?(D3、Javascript、Neo4j)