如何解决我正在寻找一对SQL函数MS SQL Server,它们将返回日期列表的MAX或MIN
我正在寻找一对SQL函数,这些函数将返回日期列表的MAX和MIN值(或者,两个日期的MAX和MIN-然后,我可以堆叠调用以处理整个列表)。我不能使用MAX()和MIN()函数(据我所知),因为这将返回特定列的最大值或最小值。我需要的是特定行的最大或最小列。
以下是一些示例数据来说明我在寻找什么:
当前查询结果:
MyID Date1 Date2 Date3 Date4
---------------------------------------------------------
ROW1 1/1/2019 4/23/2020 12/4/1980 5/2/2020
ROW2 6/3/2020 1/1/2020 5/3/2021 11/9/1998
ROW3 8/15/1980 7/4/2019 12/1/2030 1/2/2020
所需的查询结果:
MyID MaxDate MinDate
---------------------------------
ROW1 12/4/1980 5/2/2020
ROW2 11/9/1998 5/3/2021
ROW3 8/15/1980 12/1/2030
(这里,我有4个不同的日期列。根据我的实际情况,我将需要筛选8个不同的列。)
理想情况下,我希望能够执行以下操作:
SELECT
MyID,MIN(Date1,Date2,Date3,Date4),MAX(Date1,Date4)
FROM ...
或者,如有必要,我可以这样做:
SELECT
MyID,MIN(Date2,MIN(Date3,Date4))),MAX(Date2,MAX(Date3,Date4)))
FROM ...
很显然,现有的MIN和MAX函数无法以这种方式工作。有替代功能吗?我可能可以构造某种CASE子句来做到这一点,但似乎非常丑陋……使用嵌套的IF语句可能会更干净一些,尽管仍然很丑陋。发布此信息后,我将开始对此进行处理。我只是希望有一个更优雅,更干净的解决方案。
解决方法
标准的SQL解决方案是将所有日期都统一起来
SELECT MyID,MAX(thedate ) AS maxdate,MIN(thedate ) AS mindate
FROM
(
SELECT MyID,Date1 AS thedate FROM table
UNION ALL
SELECT MyID,Date2 AS thedate FROM table
UNION ALL
SELECT MyID,Date3 AS thedate FROM table
UNION ALL
SELECT MyID,Date4 AS thedate FROM table
) T
GROUP BY MyID
可能还有更好的带有窗口功能的其他解决方案,具体取决于您未指定的RDBMS。但是,该版本可以与任何RDBMS一起使用。
,大多数(但不是全部)数据库实际上支持least()
和greatest()
:
select t.*,least(date1,date2,date3,date4) as min_date,greatest(date1,date4) as max_date
from t;
唯一的警告是,如果任何值为NULL
,则返回值为NULL
。根据您问题中的示例数据,这似乎不是问题。
编辑:
在SQL Server上,您将取消透视并使用apply
:
select t.*,v.*
from t cross apply
(select max(dte) as max_date,min(dte) as min_date
from (values (t.date1),(t.date2),(t.date3),(t.date4)) v(dte)
) v
,
在这里回答我自己的问题-经过大量的挖掘,我认为目前还没有很好的解决方案。因此,我最终编写了自己的函数来处理此问题。
这是这些功能的代码:
CREATE FUNCTION dbo.maxDate(@date1 DATETIME,@date2 DATETIME) RETURNS DATETIME AS
BEGIN
DECLARE @result DATETIME
IF @date1 > @date2 SET @result = @date1
ELSE SET @result = @date2
RETURN @result
END
go
CREATE FUNCTION dbo.minDate(@date1 DATETIME,@date2 DATETIME) RETURNS DATETIME AS
BEGIN
DECLARE @result DATETIME
IF @date1 < @date2 SET @result = @date1
ELSE SET @result = @date2
RETURN @result
END
go
然后允许进行与我的问题中的第二个建议类似的查询:
SELECT
MyID,dbo.minDate(Date1,dbo.minDate(Date2,dbo.minDate(Date3,Date4))),dbo.maxDate(Date1,dbo.maxDate(Date2,dbo.maxDate(Date3,Date4)))
FROM ...
,
在SQL Server中,least()
和greatest()
不可用,我建议使用横向联接将列取消透视成行,然后聚合以提取最小值和最大值:>
select t.myid,x.*
from mytable t
cross apply (
select max(dt) maxdate,min(dt) mindate
from (values (date1),(date2),(date3)) x(dt)
) x
这比union
更有效率,因为它只扫描一次表(而不是每个union
成员一次)。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。