如何从几个可能的空白日期字段中查询最早的日期?

时间:2013-05-02 19:12:43

标签: sql ms-access

鉴于下表:

+----+----------+-----------+----------+
| ID |  date1   |   date2   |  date3   |
+----+----------+-----------+----------+
|  1 | 3/2/2013 | 5/6/2013  |          |
|  2 |          | 12/1/2011 | 6/5/2010 |
|  3 | 1/1/1936 | 1/5/1936  | 1/9/1945 |
|  4 | 2/1/2014 |           |          |
+----+----------+-----------+----------+

我想要一个返回每行最早日期的查询。至少会填充一个日期列。

我试过了:

SELECT id, 
iif(date1<date2 and date1<date3,
    date1,
    iif(date2<date1 and date2<date3,
        date2,
        date3)) as dateEarliest
FROM tbl;

但是,如果date3是最早的,那么这似乎只返回正确的结果;否则它会返回一个空白。

3 个答案:

答案 0 :(得分:4)

这可能不是“最好”的方法,但一种方法是将数据取消,以便它看起来像这样:

id  date
1   
1   3/2/2013
1   5/6/2013
2   
2   6/5/2010
2   12/1/2011
3   1/1/1936
3   1/5/1936
3   1/9/1945
4   
4   2/1/2014

这可以这样做:

SELECT id, date1 from tbl
UNION
SELECT id, date2 as date1 from tbl
UNION
SELECT id, date3 as date1 from tbl

(注意:我将日期字段命名为date1,因为date是保留关键字。)

从这里开始,您可以使用聚合函数,例如min:

select id, min(date1) as dateEarliest
from (SELECT id, date1 from tbl
UNION
SELECT id, date2 as date1 from tbl
UNION
SELECT id, date3 as date1 from tbl) unpivottbl
group by id;

哪个会给你你想要的东西。

答案 1 :(得分:2)

您无法与NULL值进行比较。使用Nz函数将NULL转换为可以比较的值。 Nz的语法是:Nz ( variant, [ value_if_null ] )

所以你会使用这样的东西:

iif(Nz(date1,#1/1/2999#) < Nz(date2,#1/1/2999#) and Nz(date1,#1/1/2999#) < (Nz(date3,#1/1/2999#)

如果在Access中使用它,并且您知道VBA,则还可以创建一个返回所需值的函数。这看起来可能更整洁:

Select id, LowDate([date1],[date2],[date3]) as dateEarliest

这是一个适合你的功能。

Function LowDate(D1, D2, D3)
   D1 = Nz(D1, #1/1/2999#)
   D2 = Nz(D2, #1/1/2999#)
   D3 = Nz(D3, #1/1/2999#)
   If D1 < D2 And D1 < D3 Then
      LowDate = D1
   ElseIf D2 < D1 And D2 < D3 Then
      LowDate = D2
   Else
      LowDate = D3
   End If
End Function

答案 2 :(得分:1)

我认为您可以将iif语句修改为:

SELECT id, 
iif((date1<date2 and date1<date3) or (date1 < date2 and date3 is null) or (date1 < date3 and date2 is null),
    date1,
    iif(date2<date1 and date2<date3) or (date2 < date1 and date3 is null) or (date2 < date3 and date2 is null),
        date2,
        date3)) as dateEarliest
FROM tbl;

如果您的空白为空,这将有效。